Compare commits
27 Commits
22d862cd12
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c50202e93b | ||
|
|
4cafe16980 | ||
|
|
fc97eb8d25 | ||
|
|
f940d2d88e | ||
|
|
9ab65e2f00 | ||
|
|
456349088e | ||
|
|
f62ca19c50 | ||
|
|
ff92f72583 | ||
|
|
83f8947ece | ||
|
|
87c1e50cf9 | ||
|
|
7f98d73738 | ||
|
|
3a5b08a4bf | ||
|
|
8b6685c501 | ||
|
|
cfb58237da | ||
|
|
aaf29ed535 | ||
|
|
6f998a497d | ||
|
|
dbf7be5104 | ||
|
|
4a4026e6dd | ||
|
|
20343b497a | ||
|
|
e4227bfda8 | ||
|
|
bb868613d9 | ||
|
|
e4d67917bd | ||
|
|
b8a701b8fe | ||
|
|
dd5e4e9a3b | ||
|
|
82b0f918dd | ||
|
|
b16fc3a64b | ||
|
|
f375f79cce |
216
CMakeLists.txt
Normal file
216
CMakeLists.txt
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
# DOS utilities for mars-nwe.
|
||||||
|
#
|
||||||
|
# Default install mode uses a split:
|
||||||
|
# - legacy command names are installed from netold.exe
|
||||||
|
# - new command names that netold.exe does not contain are installed from net.exe
|
||||||
|
#
|
||||||
|
# Maintainer mode can rebuild the new net.exe with Open Watcom. The freshly
|
||||||
|
# built binary is only installed when MARS_NWE_INSTALL_NEW_DOSUTILS is ON, or
|
||||||
|
# for the new-only command names in the default split install.
|
||||||
|
|
||||||
|
set(MARS_DOSUTILS_LEGACY_NET_EXE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/netold.exe"
|
||||||
|
CACHE FILEPATH "Legacy/pre-Client32 DOS net.exe used by default for legacy command names"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MARS_DOSUTILS_NEW_NET_EXE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/net.exe"
|
||||||
|
CACHE FILEPATH "New/experimental DOS net.exe used for new-only tools or when MARS_NWE_INSTALL_NEW_DOSUTILS is ON"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MARS_DOSUTILS_LEGACY_TOOLS
|
||||||
|
net
|
||||||
|
login
|
||||||
|
profile
|
||||||
|
spawn
|
||||||
|
passwd
|
||||||
|
path
|
||||||
|
pathins
|
||||||
|
pathdel
|
||||||
|
map
|
||||||
|
mapdel
|
||||||
|
logout
|
||||||
|
capture
|
||||||
|
endcap
|
||||||
|
)
|
||||||
|
|
||||||
|
# Tools not present in netold.exe. These are installed from the new binary
|
||||||
|
# even in the default split mode.
|
||||||
|
set(MARS_DOSUTILS_NEW_ONLY_TOOLS
|
||||||
|
slist
|
||||||
|
flag
|
||||||
|
flagdir
|
||||||
|
rights
|
||||||
|
grant
|
||||||
|
revoke
|
||||||
|
remove
|
||||||
|
)
|
||||||
|
|
||||||
|
if(MARS_NWE_BUILD_DOSUTILS)
|
||||||
|
find_package(OpenWatcom REQUIRED)
|
||||||
|
|
||||||
|
set(DOSUTILS_C_SOURCES
|
||||||
|
net.c
|
||||||
|
tools.c
|
||||||
|
netcall.c
|
||||||
|
ncpcall.c
|
||||||
|
login.c
|
||||||
|
map.c
|
||||||
|
slist.c
|
||||||
|
flag.c
|
||||||
|
flagdir.c
|
||||||
|
rights.c
|
||||||
|
grant.c
|
||||||
|
revoke.c
|
||||||
|
remove.c
|
||||||
|
trustee.c
|
||||||
|
c32ncp.c
|
||||||
|
nwcrypt.c
|
||||||
|
nwdebug.c
|
||||||
|
nwtests.c
|
||||||
|
capture.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/kern.obj"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E env ${OPENWATCOM_ENV}
|
||||||
|
"${OPENWATCOM_WASM}"
|
||||||
|
-q
|
||||||
|
-zq
|
||||||
|
-fo="${CMAKE_CURRENT_BINARY_DIR}/kern.obj"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/kern_wasm.asm"
|
||||||
|
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/kern_wasm.asm"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
set(DOSUTILS_OBJECTS)
|
||||||
|
foreach(src IN LISTS DOSUTILS_C_SOURCES)
|
||||||
|
get_filename_component(obj_name "${src}" NAME_WE)
|
||||||
|
set(obj "${CMAKE_CURRENT_BINARY_DIR}/${obj_name}.obj")
|
||||||
|
list(APPEND DOSUTILS_OBJECTS "${obj}")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${obj}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E env ${OPENWATCOM_ENV}
|
||||||
|
"${OPENWATCOM_WCL}"
|
||||||
|
-q
|
||||||
|
-zq
|
||||||
|
-bt=dos
|
||||||
|
-ml
|
||||||
|
-0
|
||||||
|
-c
|
||||||
|
-fo="${obj}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${src}"
|
||||||
|
DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${src}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/net.h"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/kern.h"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/c32ncp.h"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/nwcrypt.h"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/net.exe"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E env ${OPENWATCOM_ENV}
|
||||||
|
"${OPENWATCOM_WCL}"
|
||||||
|
-q
|
||||||
|
-zq
|
||||||
|
-bt=dos
|
||||||
|
-ml
|
||||||
|
-0
|
||||||
|
-k32768
|
||||||
|
-fe="${CMAKE_CURRENT_BINARY_DIR}/net.exe"
|
||||||
|
${DOSUTILS_OBJECTS}
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/kern.obj"
|
||||||
|
DEPENDS
|
||||||
|
${DOSUTILS_OBJECTS}
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/kern.obj"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(dosutils_net ALL
|
||||||
|
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/net.exe"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MARS_DOSUTILS_BUILT_NET_EXE "${CMAKE_CURRENT_BINARY_DIR}/net.exe")
|
||||||
|
else()
|
||||||
|
set(MARS_DOSUTILS_BUILT_NET_EXE "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MARS_NWE_BUILD_DOSUTILS)
|
||||||
|
set(MARS_DOSUTILS_SELECTED_NEW_EXE "${MARS_DOSUTILS_BUILT_NET_EXE}")
|
||||||
|
else()
|
||||||
|
set(MARS_DOSUTILS_SELECTED_NEW_EXE "${MARS_DOSUTILS_NEW_NET_EXE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MARS_NWE_INSTALL_NEW_DOSUTILS)
|
||||||
|
set(MARS_DOSUTILS_SELECTED_LEGACY_EXE "${MARS_DOSUTILS_SELECTED_NEW_EXE}")
|
||||||
|
else()
|
||||||
|
set(MARS_DOSUTILS_SELECTED_LEGACY_EXE "${MARS_DOSUTILS_LEGACY_NET_EXE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(MARS_DOSUTILS_SELECTED_LEGACY_IS_BUILT FALSE)
|
||||||
|
set(MARS_DOSUTILS_SELECTED_NEW_IS_BUILT FALSE)
|
||||||
|
if(MARS_NWE_BUILD_DOSUTILS)
|
||||||
|
if(MARS_DOSUTILS_SELECTED_LEGACY_EXE STREQUAL MARS_DOSUTILS_BUILT_NET_EXE)
|
||||||
|
set(MARS_DOSUTILS_SELECTED_LEGACY_IS_BUILT TRUE)
|
||||||
|
endif()
|
||||||
|
if(MARS_DOSUTILS_SELECTED_NEW_EXE STREQUAL MARS_DOSUTILS_BUILT_NET_EXE)
|
||||||
|
set(MARS_DOSUTILS_SELECTED_NEW_IS_BUILT TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MARS_NWE_INSTALL_DOSUTILS)
|
||||||
|
if(NOT MARS_DOSUTILS_SELECTED_LEGACY_IS_BUILT AND NOT EXISTS "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Selected legacy/default DOS utility missing: ${MARS_DOSUTILS_SELECTED_LEGACY_EXE}. "
|
||||||
|
"Commit dosutils/netold.exe, enable MARS_NWE_INSTALL_NEW_DOSUTILS, "
|
||||||
|
"or enable MARS_NWE_BUILD_DOSUTILS."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT MARS_DOSUTILS_SELECTED_NEW_IS_BUILT AND NOT EXISTS "${MARS_DOSUTILS_SELECTED_NEW_EXE}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Selected new DOS utility missing: ${MARS_DOSUTILS_SELECTED_NEW_EXE}. "
|
||||||
|
"Commit dosutils/net.exe or enable MARS_NWE_BUILD_DOSUTILS."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "DOS legacy/default utility binary: ${MARS_DOSUTILS_SELECTED_LEGACY_EXE}")
|
||||||
|
message(STATUS "DOS new-only utility binary: ${MARS_DOSUTILS_SELECTED_NEW_EXE}")
|
||||||
|
|
||||||
|
foreach(tool IN LISTS MARS_DOSUTILS_LEGACY_TOOLS)
|
||||||
|
if(tool STREQUAL "net")
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public"
|
||||||
|
RENAME net.exe)
|
||||||
|
else()
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public"
|
||||||
|
RENAME "${tool}.exe")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(tool IN LISTS MARS_DOSUTILS_NEW_ONLY_TOOLS)
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_NEW_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/public"
|
||||||
|
RENAME "${tool}.exe")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login"
|
||||||
|
RENAME login.exe)
|
||||||
|
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login"
|
||||||
|
RENAME map.exe)
|
||||||
|
|
||||||
|
install(FILES "${MARS_DOSUTILS_SELECTED_LEGACY_EXE}"
|
||||||
|
DESTINATION "${MARS_NWE_INSTALL_FULL_FILEDIR}/SYS/login"
|
||||||
|
RENAME slist.exe)
|
||||||
|
endif()
|
||||||
653
README.md
Normal file
653
README.md
Normal file
@@ -0,0 +1,653 @@
|
|||||||
|
# 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 FLAG-family and trustee/right tools.
|
||||||
|
|
||||||
|
Validated recently:
|
||||||
|
|
||||||
|
- `FLAG` file attribute read/modify through DOS Client32
|
||||||
|
- `FLAGDIR` directory attribute read/modify through DOS Client32
|
||||||
|
- `RIGHTS` effective-rights display through Client32 NCP87
|
||||||
|
- `GRANT` trustee assignment for users and groups
|
||||||
|
- `REVOKE` trustee-right removal for users and groups
|
||||||
|
- `REMOVE` trustee deletion for users and groups
|
||||||
|
- Novell-tool comparison for `FLAG`, including `ALL`, `N`, `RO`, `RW`, high bits, and display layout
|
||||||
|
- Novell-tool comparison for `FLAGDIR`, including `Normal`, `System`, `Hidden`, `DeleteInhibit`, `Purge`, `RenameInhibit`, and combined attributes
|
||||||
|
- Novell-tool comparison for `RIGHTS`, `GRANT`, `REVOKE`, and `REMOVE`
|
||||||
|
- CMake/Open Watcom build using binary-directory object files, so `.obj`/`.o` files are no longer written into the source tree
|
||||||
|
|
||||||
|
Still to validate or continue:
|
||||||
|
|
||||||
|
- DOSX/VLM/NETX fallback behavior for `FLAG` and `FLAGDIR`
|
||||||
|
- More complex `FLAGDIR` paths beyond the simple mapped-directory cases already tested
|
||||||
|
- OS/2 requester/tool behavior
|
||||||
|
- Additional Novell-like utilities such as `NDIR`, `PURGE`, and `SALVAGE`
|
||||||
|
|
||||||
|
## 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`
|
||||||
|
- 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`
|
||||||
|
- `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
|
||||||
|
```
|
||||||
|
|
||||||
|
## Client32 NCP support
|
||||||
|
|
||||||
|
The modern Client32 path is implemented through a small reusable helper layer:
|
||||||
|
|
||||||
|
- `c32ncp.c`
|
||||||
|
- `c32ncp.h`
|
||||||
|
- Client32 assembly entry points in `kern_wasm.asm`
|
||||||
|
|
||||||
|
The working sequence is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
C32_MapVar_Probe(4,0)
|
||||||
|
-> obtains the active connection reference
|
||||||
|
|
||||||
|
C32_OpenRef_Probe()
|
||||||
|
-> opens that reference and returns a Client32 handle
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe()
|
||||||
|
-> 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 is 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.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### `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 `kern_wasm.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`
|
||||||
|
- `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
|
||||||
|
|
||||||
|
- `kern_wasm.asm` is the 16-bit Open Watcom assembly implementation used by the modern build.
|
||||||
|
- `kern.c` was an experimental C-side test wrapper and is no longer required by the current Client32 FLAG/FLAGDIR path.
|
||||||
|
- `c32ncp.c` and `c32ncp.h` contain reusable Client32 NCP helper functions for DOS tools.
|
||||||
|
- `trustee.c` and `trustee.h` contain shared 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.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
No standalone license file is included in the provided snapshot. The source files do contain copyright notices naming Martin Stover. Anyone planning to redistribute or modernize the project should verify licensing status before publishing derivative releases.
|
||||||
777
c32ncp.c
Normal file
777
c32ncp.c
Normal file
@@ -0,0 +1,777 @@
|
|||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
|
||||||
|
/* c32ncp.c - Client32 NCP helpers for mars-dosutils */
|
||||||
|
static void c32_put_word_lh(uint8 *p, uint16 v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8)(v & 0xff);
|
||||||
|
p[1] = (uint8)((v >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void c32_put_dword_lh(uint8 *p, uint32 v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8)(v & 0xff);
|
||||||
|
p[1] = (uint8)((v >> 8) & 0xff);
|
||||||
|
p[2] = (uint8)((v >> 16) & 0xff);
|
||||||
|
p[3] = (uint8)((v >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void c32_put_dword_hl(uint8 *p, uint32 v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8)((v >> 24) & 0xff);
|
||||||
|
p[1] = (uint8)((v >> 16) & 0xff);
|
||||||
|
p[2] = (uint8)((v >> 8) & 0xff);
|
||||||
|
p[3] = (uint8)(v & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16 c32_get_word_lh(uint8 *p)
|
||||||
|
{
|
||||||
|
return((uint16)(p[0] | ((uint16)p[1] << 8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 c32_get_dword_lh(uint8 *p)
|
||||||
|
{
|
||||||
|
return((uint32)p[0] |
|
||||||
|
((uint32)p[1] << 8) |
|
||||||
|
((uint32)p[2] << 16) |
|
||||||
|
((uint32)p[3] << 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 c32_get_dword_hl(uint8 *p)
|
||||||
|
{
|
||||||
|
return(((uint32)p[0] << 24) |
|
||||||
|
((uint32)p[1] << 16) |
|
||||||
|
((uint32)p[2] << 8) |
|
||||||
|
(uint32)p[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UI c32_build_handle_path(uint8 *buf, uint8 dhandle,
|
||||||
|
uint16 dirbase, uint8 style,
|
||||||
|
int count,
|
||||||
|
const char *c1, const char *c2, const char *c3)
|
||||||
|
{
|
||||||
|
uint8 *p;
|
||||||
|
int l;
|
||||||
|
UI used;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeveloperNet/ncpdos16 path structure used by NCP87/S6 through
|
||||||
|
* Client32 COMPATNcpRequestReply.
|
||||||
|
*
|
||||||
|
* This is the exact shape verified by TESTS NCP87C32AUTO:
|
||||||
|
* 00 02 00 00 00 00 01 09 4C 4F 47 49 4E 2E 45 58 45
|
||||||
|
*
|
||||||
|
* Meaning:
|
||||||
|
* word[1] = short dir handle
|
||||||
|
* word[3] = dir base
|
||||||
|
* byte[5] = dirstyle
|
||||||
|
* byte[6] = component count
|
||||||
|
* then len/name components
|
||||||
|
*
|
||||||
|
* The old/simple struct used by the INT 21h F257 fallback is not accepted
|
||||||
|
* by this Client32 path.
|
||||||
|
*/
|
||||||
|
memset(buf, 0, 0x140);
|
||||||
|
|
||||||
|
if (dhandle) {
|
||||||
|
c32_put_word_lh(buf + 1, (uint16)dhandle);
|
||||||
|
c32_put_word_lh(buf + 3, dirbase);
|
||||||
|
buf[5] = style;
|
||||||
|
} else {
|
||||||
|
buf[5] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = buf + 6;
|
||||||
|
*p++ = (uint8)count;
|
||||||
|
|
||||||
|
if (count > 0 && c1) {
|
||||||
|
l = strlen(c1);
|
||||||
|
if (l > 255) l = 255;
|
||||||
|
*p++ = (uint8)l;
|
||||||
|
memcpy(p, c1, l);
|
||||||
|
p += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1 && c2) {
|
||||||
|
l = strlen(c2);
|
||||||
|
if (l > 255) l = 255;
|
||||||
|
*p++ = (uint8)l;
|
||||||
|
memcpy(p, c2, l);
|
||||||
|
p += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 2 && c3) {
|
||||||
|
l = strlen(c3);
|
||||||
|
if (l > 255) l = 255;
|
||||||
|
*p++ = (uint8)l;
|
||||||
|
memcpy(p, c3, l);
|
||||||
|
p += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
used = (UI)(p - buf);
|
||||||
|
c32_put_word_lh(buf + 0x13c, used);
|
||||||
|
return(used);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static UI c32_build_handle_path_from_dos_path(uint8 *buf, uint8 dhandle,
|
||||||
|
uint16 dirbase, uint8 style,
|
||||||
|
const char *dospath)
|
||||||
|
{
|
||||||
|
uint8 *p;
|
||||||
|
uint8 *countp;
|
||||||
|
int count = 0;
|
||||||
|
const char *s;
|
||||||
|
UI used;
|
||||||
|
|
||||||
|
memset(buf, 0, 0x140);
|
||||||
|
|
||||||
|
if (dhandle) {
|
||||||
|
c32_put_word_lh(buf + 1, (uint16)dhandle);
|
||||||
|
c32_put_word_lh(buf + 3, dirbase);
|
||||||
|
buf[5] = style;
|
||||||
|
} else {
|
||||||
|
buf[5] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = buf + 6;
|
||||||
|
countp = p++;
|
||||||
|
|
||||||
|
s = dospath;
|
||||||
|
if (!s) s = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DOS tools mostly pass relative paths against the current directory
|
||||||
|
* handle. Accept simple DOS decoration here so RIGHTS can pass "." or
|
||||||
|
* ".\\UDIR\\FILE" without constructing path components in the caller.
|
||||||
|
*/
|
||||||
|
if (s[0] && s[1] == ':')
|
||||||
|
s += 2;
|
||||||
|
|
||||||
|
while (*s == '\\' || *s == '/')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
while (*s && p < buf + 0x138 && count < 32) {
|
||||||
|
const char *start;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while (*s == '\\' || *s == '/')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
if (*s == '.'
|
||||||
|
&& (s[1] == '\0' || s[1] == '\\' || s[1] == '/')) {
|
||||||
|
s++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = s;
|
||||||
|
while (*s && *s != '\\' && *s != '/')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
len = (int)(s - start);
|
||||||
|
if (len <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
if (p + 1 + len >= buf + 0x138)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*p++ = (uint8)len;
|
||||||
|
memcpy(p, start, len);
|
||||||
|
p += len;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*countp = (uint8)count;
|
||||||
|
|
||||||
|
used = (UI)(p - buf);
|
||||||
|
c32_put_word_lh(buf + 0x13c, used);
|
||||||
|
return(used);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current verified Client32 path for mars-nwe DOS utilities:
|
||||||
|
*
|
||||||
|
* C32_MapVar_Probe(4,0) -> connRefLocal FFFF:FFFE
|
||||||
|
* C32_OpenRef_Probe(connRefLocal) -> Client32 handle, e.g. 0101:0001
|
||||||
|
*
|
||||||
|
* C32_MapVar_Probe currently contains the confirmed Mars server-name scan
|
||||||
|
* shape. It is intentionally kept small and isolated here so FLAG and later
|
||||||
|
* tools do not carry the old exploratory tests.
|
||||||
|
*/
|
||||||
|
int c32_get_ncp_handle(uint16 *handle_lo, uint16 *handle_hi)
|
||||||
|
{
|
||||||
|
uint8 mapout[32];
|
||||||
|
uint8 openout[32];
|
||||||
|
uint16 map_ret_ax, map_ret_dx;
|
||||||
|
uint16 cref_lo, cref_hi;
|
||||||
|
uint16 open_ret_ax, open_ret_dx;
|
||||||
|
|
||||||
|
if (!handle_lo || !handle_hi)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
*handle_lo = 0;
|
||||||
|
*handle_hi = 0;
|
||||||
|
|
||||||
|
memset(mapout, 0, sizeof(mapout));
|
||||||
|
C32_MapVar_Probe(4, 0, mapout);
|
||||||
|
|
||||||
|
map_ret_ax = c32_get_word_lh(mapout + 14);
|
||||||
|
map_ret_dx = c32_get_word_lh(mapout + 16);
|
||||||
|
cref_lo = c32_get_word_lh(mapout + 22);
|
||||||
|
cref_hi = c32_get_word_lh(mapout + 24);
|
||||||
|
|
||||||
|
if (map_ret_ax != 0 || map_ret_dx != 0 || (cref_lo == 0 && cref_hi == 0))
|
||||||
|
return(2);
|
||||||
|
|
||||||
|
memset(openout, 0, sizeof(openout));
|
||||||
|
C32_OpenRef_Probe(cref_lo, cref_hi, openout);
|
||||||
|
|
||||||
|
open_ret_ax = c32_get_word_lh(openout + 14);
|
||||||
|
open_ret_dx = c32_get_word_lh(openout + 16);
|
||||||
|
*handle_lo = c32_get_word_lh(openout + 18);
|
||||||
|
*handle_hi = c32_get_word_lh(openout + 20);
|
||||||
|
|
||||||
|
if (open_ret_ax != 0 || open_ret_dx != 0 || (*handle_lo == 0 && *handle_hi == 0))
|
||||||
|
return(3);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int c32_ncp87_obtain_rim_attributes(const char *name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 *attr_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 hdr[16];
|
||||||
|
uint8 path[0x140];
|
||||||
|
uint8 rep0[0x60];
|
||||||
|
uint8 rep1[0x110];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
int path_len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!name || !attr_out)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
*attr_out = 0;
|
||||||
|
if (actual_out) *actual_out = 0;
|
||||||
|
if (handle_lo_out) *handle_lo_out = 0;
|
||||||
|
if (handle_hi_out) *handle_hi_out = 0;
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0] = 6; /* NCP87 subfunction 6 */
|
||||||
|
hdr[1] = 0; /* source namespace DOS */
|
||||||
|
hdr[2] = 0; /* target namespace DOS */
|
||||||
|
c32_put_word_lh(hdr + 3, 0x0006); /* SA_ALL */
|
||||||
|
c32_put_dword_lh(hdr + 5, 0x00000004UL); /* RIM_ATTRIBUTES */
|
||||||
|
|
||||||
|
path_len = c32_build_handle_path(path, (uint8)dir_handle, 0, 0, 1,
|
||||||
|
name, NULL, NULL);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
hdr, 9,
|
||||||
|
path, (UI)path_len,
|
||||||
|
rep0, 0x4d,
|
||||||
|
rep1, 0x100,
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(20);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verified reply layout for RIM_ATTRIBUTES:
|
||||||
|
* REP0+4 little-endian dword = DOS attributes
|
||||||
|
* Example LOGIN.EXE: 20h archive.
|
||||||
|
*/
|
||||||
|
*attr_out = c32_get_dword_lh(rep0 + 4);
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = actual_lo;
|
||||||
|
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int c32_ncp87_modify_dos_attributes(char *name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 attrs,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 modbuf[64];
|
||||||
|
uint8 path[0x140];
|
||||||
|
uint8 rep0[0x20];
|
||||||
|
uint8 rep1[0x20];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint8 *p;
|
||||||
|
UI mod_len;
|
||||||
|
UI path_len;
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
if (actual_out)
|
||||||
|
*actual_out = 0;
|
||||||
|
if (handle_lo_out)
|
||||||
|
*handle_lo_out = 0;
|
||||||
|
if (handle_hi_out)
|
||||||
|
*handle_hi_out = 0;
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NCP 87 subfunction 7: Modify DOS information.
|
||||||
|
*
|
||||||
|
* First request fragment contains the fixed header and DOS info structure.
|
||||||
|
* Second request fragment contains the verified SDK-style path structure.
|
||||||
|
*
|
||||||
|
* This avoids the old INT 21h F257 modify path, which can hang under DOS
|
||||||
|
* Client32 for high FLAG bits such as Transactional.
|
||||||
|
*/
|
||||||
|
memset(modbuf, 0, sizeof(modbuf));
|
||||||
|
p = modbuf;
|
||||||
|
|
||||||
|
*p++ = 7; /* subfunction: modify DOS info */
|
||||||
|
*p++ = 0; /* namespace DOS */
|
||||||
|
*p++ = 0; /* reserved */
|
||||||
|
c32_put_word_lh(p, 0x0006); p += 2; /* SA_ALL */
|
||||||
|
c32_put_dword_lh(p, 0x00000002UL); p += 4; /* DM_ATTRIBUTES: attributes */
|
||||||
|
|
||||||
|
c32_put_dword_lh(p, attrs); p += 4; /* Attributes */
|
||||||
|
memset(p, 0, 34); p += 34; /* rest of DOS info */
|
||||||
|
mod_len = (UI)(p - modbuf);
|
||||||
|
|
||||||
|
path_len = c32_build_handle_path(path, (uint8)dir_handle, 0, 0, 1,
|
||||||
|
name, NULL, NULL);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
modbuf, mod_len,
|
||||||
|
path, path_len,
|
||||||
|
rep0, sizeof(rep0),
|
||||||
|
rep1, sizeof(rep1),
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (actual_out)
|
||||||
|
*actual_out = actual_lo;
|
||||||
|
if (handle_lo_out)
|
||||||
|
*handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out)
|
||||||
|
*handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(20);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int c32_ncp87_get_effective_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint16 *rights_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 hdr[16];
|
||||||
|
uint8 path[0x140];
|
||||||
|
uint8 rep0[0x20];
|
||||||
|
uint8 rep1[0x20];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
uint16 rights0;
|
||||||
|
uint16 rights4;
|
||||||
|
UI path_len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!rights_out)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
*rights_out = 0;
|
||||||
|
if (actual_out) *actual_out = 0;
|
||||||
|
if (handle_lo_out) *handle_lo_out = 0;
|
||||||
|
if (handle_hi_out) *handle_hi_out = 0;
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NCP 87 subfunction 29: Get effective rights.
|
||||||
|
*
|
||||||
|
* This mirrors ncpfs ncp_get_eff_directory_rights():
|
||||||
|
* byte 29
|
||||||
|
* byte source namespace
|
||||||
|
* byte target namespace
|
||||||
|
* word search attributes, little endian
|
||||||
|
* dword reserved, zero
|
||||||
|
* handle/path
|
||||||
|
*
|
||||||
|
* Reply is a little-endian word with NCP rights bits.
|
||||||
|
*/
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0] = 29;
|
||||||
|
hdr[1] = 0; /* source namespace DOS */
|
||||||
|
hdr[2] = 0; /* target namespace DOS */
|
||||||
|
c32_put_word_lh(hdr + 3, 0x0006); /* SA_ALL */
|
||||||
|
c32_put_dword_lh(hdr + 5, 0L); /* reserved */
|
||||||
|
|
||||||
|
path_len = c32_build_handle_path_from_dos_path(path, (uint8)dir_handle,
|
||||||
|
0, 0, path_name);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
hdr, 9,
|
||||||
|
path, path_len,
|
||||||
|
rep0, sizeof(rep0),
|
||||||
|
rep1, sizeof(rep1),
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = actual_lo;
|
||||||
|
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(20);
|
||||||
|
|
||||||
|
rights0 = c32_get_word_lh(rep0 + 0);
|
||||||
|
rights4 = c32_get_word_lh(rep0 + 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Most NCP replies start at REP0+0. The existing RIM_ATTRIBUTES helper
|
||||||
|
* found attributes at REP0+4 on Client32. Accept the +4 location only
|
||||||
|
* if +0 is empty, so restricted rights value 0 still works when +4 is
|
||||||
|
* also zero.
|
||||||
|
*/
|
||||||
|
if (rights0 == 0 && rights4 != 0)
|
||||||
|
rights0 = rights4;
|
||||||
|
|
||||||
|
*rights_out = rights0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int c32_ncp87_add_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 rights,
|
||||||
|
uint16 rights_mask,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 hdr[16];
|
||||||
|
uint8 reqpath[0x180];
|
||||||
|
uint8 rep0[0x20];
|
||||||
|
uint8 rep1[0x20];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
UI path_struct_len;
|
||||||
|
UI reqpath_len;
|
||||||
|
uint8 *tp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = 0;
|
||||||
|
if (handle_lo_out) *handle_lo_out = 0;
|
||||||
|
if (handle_hi_out) *handle_hi_out = 0;
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NCP 87 subfunction 10: Add trustee.
|
||||||
|
*
|
||||||
|
* This mirrors ncpfs ncp_ns_trustee_add():
|
||||||
|
* byte 10
|
||||||
|
* byte namespace DOS
|
||||||
|
* byte reserved
|
||||||
|
* word search attributes, little endian
|
||||||
|
* word rights mask, little endian
|
||||||
|
* word object count, little endian
|
||||||
|
* handle/path
|
||||||
|
* trustee array at request offset 16 + 307
|
||||||
|
*
|
||||||
|
* Client32 Raw5 has two request fragments, so the second fragment carries
|
||||||
|
* the handle/path and the padded trustee record.
|
||||||
|
*/
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0] = 10;
|
||||||
|
hdr[1] = 0; /* DOS namespace */
|
||||||
|
hdr[2] = 0; /* reserved */
|
||||||
|
c32_put_word_lh(hdr + 3, 0x8006); /* SA_ALL: files/subdirs + system + hidden */
|
||||||
|
c32_put_word_lh(hdr + 5, rights_mask);
|
||||||
|
c32_put_word_lh(hdr + 7, 1); /* one trustee */
|
||||||
|
|
||||||
|
memset(reqpath, 0, sizeof(reqpath));
|
||||||
|
path_struct_len = c32_build_handle_path_from_dos_path(reqpath,
|
||||||
|
(uint8)dir_handle,
|
||||||
|
0, 0,
|
||||||
|
path_name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ncpfs seeks to absolute packet offset 16+307 before writing the
|
||||||
|
* trustee list. The NCP request header is 7 bytes, so inside the NCP
|
||||||
|
* payload the trustee list begins at:
|
||||||
|
*
|
||||||
|
* (16 + 307) - 7 = 316
|
||||||
|
*
|
||||||
|
* Our first Raw5 request fragment is the 9-byte subfunction header,
|
||||||
|
* so the trustee list begins in the second fragment at:
|
||||||
|
*
|
||||||
|
* 316 - 9 = 307
|
||||||
|
*/
|
||||||
|
if (path_struct_len > 307)
|
||||||
|
return(2);
|
||||||
|
|
||||||
|
tp = reqpath + 307;
|
||||||
|
c32_put_dword_hl(tp, object_id); tp += 4;
|
||||||
|
c32_put_word_lh(tp, rights); tp += 2;
|
||||||
|
reqpath_len = (UI)(tp - reqpath);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
hdr, 9,
|
||||||
|
reqpath, reqpath_len,
|
||||||
|
rep0, sizeof(rep0),
|
||||||
|
rep1, sizeof(rep1),
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = actual_lo;
|
||||||
|
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(20);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int c32_ncp87_find_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 *rights_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 hdr[16];
|
||||||
|
uint8 path[0x140];
|
||||||
|
uint8 rep0[0x120];
|
||||||
|
uint8 rep1[0x120];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
uint32 seq = 0;
|
||||||
|
UI path_len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (rights_out) *rights_out = 0;
|
||||||
|
if (actual_out) *actual_out = 0;
|
||||||
|
if (handle_lo_out) *handle_lo_out = 0;
|
||||||
|
if (handle_hi_out) *handle_hi_out = 0;
|
||||||
|
|
||||||
|
if (!rights_out)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
uint16 count;
|
||||||
|
uint16 i;
|
||||||
|
uint8 *tp;
|
||||||
|
uint32 next_seq;
|
||||||
|
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0] = 5; /* NCP87 subfunction 5: scan trustees */
|
||||||
|
hdr[1] = 0; /* DOS namespace */
|
||||||
|
hdr[2] = 0; /* reserved */
|
||||||
|
c32_put_word_lh(hdr + 3, 0x8006); /* SA_ALL: files/subdirs + system + hidden */
|
||||||
|
c32_put_dword_lh(hdr + 5, seq); /* search sequence, starts at zero */
|
||||||
|
|
||||||
|
path_len = c32_build_handle_path_from_dos_path(path,
|
||||||
|
(uint8)dir_handle,
|
||||||
|
0, 0,
|
||||||
|
path_name);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
hdr, 9,
|
||||||
|
path, path_len,
|
||||||
|
rep0, sizeof(rep0),
|
||||||
|
rep1, sizeof(rep1),
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = actual_lo;
|
||||||
|
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(0xff); /* Client32 returns an error when no trustees are present. */
|
||||||
|
|
||||||
|
next_seq = c32_get_dword_lh(rep0 + 0);
|
||||||
|
count = c32_get_word_lh(rep0 + 4);
|
||||||
|
|
||||||
|
if (count > 20)
|
||||||
|
count = 20;
|
||||||
|
|
||||||
|
tp = rep0 + 6;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
uint32 tid = c32_get_dword_hl(tp);
|
||||||
|
uint16 trights = c32_get_word_lh(tp + 4);
|
||||||
|
|
||||||
|
if (tid == object_id || c32_get_dword_lh(tp) == object_id) {
|
||||||
|
*rights_out = trights;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tp += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_seq == 0xffffffffUL || next_seq == seq)
|
||||||
|
break;
|
||||||
|
|
||||||
|
seq = next_seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0xff); /* no trustee found / no more entries */
|
||||||
|
}
|
||||||
|
|
||||||
|
int c32_ncp87_delete_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out)
|
||||||
|
{
|
||||||
|
uint16 handle_lo, handle_hi;
|
||||||
|
uint8 hdr[16];
|
||||||
|
uint8 reqpath[0x180];
|
||||||
|
uint8 rep0[0x20];
|
||||||
|
uint8 rep1[0x20];
|
||||||
|
uint8 rawout[32];
|
||||||
|
uint16 raw_ret_ax, raw_ret_dx;
|
||||||
|
uint16 actual_lo;
|
||||||
|
UI path_struct_len;
|
||||||
|
UI reqpath_len;
|
||||||
|
uint8 *tp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = 0;
|
||||||
|
if (handle_lo_out) *handle_lo_out = 0;
|
||||||
|
if (handle_hi_out) *handle_hi_out = 0;
|
||||||
|
|
||||||
|
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||||
|
if (rc)
|
||||||
|
return(10 + rc);
|
||||||
|
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0] = 11; /* NCP87 subfunction 11: delete trustee */
|
||||||
|
hdr[1] = 0; /* DOS namespace */
|
||||||
|
hdr[2] = 0; /* reserved */
|
||||||
|
c32_put_word_lh(hdr + 3, 1); /* one trustee */
|
||||||
|
|
||||||
|
memset(reqpath, 0, sizeof(reqpath));
|
||||||
|
path_struct_len = c32_build_handle_path_from_dos_path(reqpath,
|
||||||
|
(uint8)dir_handle,
|
||||||
|
0, 0,
|
||||||
|
path_name);
|
||||||
|
|
||||||
|
if (path_struct_len > 307)
|
||||||
|
return(2);
|
||||||
|
|
||||||
|
tp = reqpath + 307;
|
||||||
|
c32_put_dword_hl(tp, object_id); tp += 4;
|
||||||
|
c32_put_word_lh(tp, 0); tp += 2;
|
||||||
|
reqpath_len = (UI)(tp - reqpath);
|
||||||
|
|
||||||
|
memset(rep0, 0, sizeof(rep0));
|
||||||
|
memset(rep1, 0, sizeof(rep1));
|
||||||
|
memset(rawout, 0, sizeof(rawout));
|
||||||
|
|
||||||
|
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||||
|
hdr, 5,
|
||||||
|
reqpath, reqpath_len,
|
||||||
|
rep0, sizeof(rep0),
|
||||||
|
rep1, sizeof(rep1),
|
||||||
|
rawout);
|
||||||
|
|
||||||
|
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||||
|
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||||
|
actual_lo = c32_get_word_lh(rawout + 18);
|
||||||
|
|
||||||
|
if (actual_out) *actual_out = actual_lo;
|
||||||
|
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||||
|
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||||
|
|
||||||
|
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||||
|
return(20);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
53
c32ncp.h
Normal file
53
c32ncp.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* c32ncp.h - minimal Client32 NCP helpers for mars-dosutils */
|
||||||
|
|
||||||
|
#ifndef C32NCP_H
|
||||||
|
#define C32NCP_H
|
||||||
|
int c32_get_ncp_handle(uint16 *handle_lo, uint16 *handle_hi);
|
||||||
|
|
||||||
|
int c32_ncp87_obtain_rim_attributes(const char *name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 *attr_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
|
||||||
|
int c32_ncp87_modify_dos_attributes(char *name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 attrs,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
int c32_ncp87_get_effective_rights(const char *path,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint16 *rights_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
int c32_ncp87_add_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 rights,
|
||||||
|
uint16 rights_mask,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
int c32_ncp87_find_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 *rights_out,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
int c32_ncp87_delete_trustee_rights(const char *path_name,
|
||||||
|
uint16 dir_handle,
|
||||||
|
uint32 object_id,
|
||||||
|
uint16 *actual_out,
|
||||||
|
uint16 *handle_lo_out,
|
||||||
|
uint16 *handle_hi_out);
|
||||||
|
|
||||||
|
#endif
|
||||||
80
capture.c
Normal file
80
capture.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/* capture.c 05-Apr-96 */
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
static int usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:\t%s level\n", funcname);
|
||||||
|
fprintf(stderr, "\tlevel=0 .. 99\n" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_argv(uint8 *devname, uint8 *queuename,
|
||||||
|
int argc, char *argv[], int parsemode)
|
||||||
|
{
|
||||||
|
int k = 0;
|
||||||
|
*devname = '\0';
|
||||||
|
*queuename = '\0';
|
||||||
|
while (++k < argc) {
|
||||||
|
uint8 *p = argv[k];
|
||||||
|
if (k == 1) {
|
||||||
|
strmaxcpy(devname, p, 20);
|
||||||
|
upstr(devname);
|
||||||
|
if (!strcmp(devname, "PRN"))
|
||||||
|
strcpy(devname, "LPT1");
|
||||||
|
} else if (k == 2) {
|
||||||
|
strmaxcpy(queuename, p, 20);
|
||||||
|
upstr(queuename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_capture(uint8 *drvstr, uint8 *queuestr, int delete)
|
||||||
|
{
|
||||||
|
int result = redir_device_drive(delete ? -1 : 0x3, drvstr, queuestr);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int show_capture(uint8 *drvstr)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int k =-1;
|
||||||
|
uint8 devname[20];
|
||||||
|
uint8 remotename[130];
|
||||||
|
int devicetyp;
|
||||||
|
while ((result = list_redir(++k, &devicetyp, devname, remotename)) > -1){
|
||||||
|
if (result > -1 && devicetyp == 0x3) {
|
||||||
|
upstr(devname);
|
||||||
|
upstr(remotename);
|
||||||
|
if (!drvstr || !*drvstr || !strcmp(devname, drvstr))
|
||||||
|
fprintf(stdout, "%-10s captured to %s\n", devname, remotename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_capture(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
uint8 devname [22];
|
||||||
|
uint8 queuestr[22];
|
||||||
|
if (!parse_argv(devname, queuestr, argc, argv, mode)) {
|
||||||
|
int result=0;
|
||||||
|
if (*queuestr || mode == 1) {
|
||||||
|
result=do_capture(devname, queuestr, mode);
|
||||||
|
if (result< 0)
|
||||||
|
fprintf(stderr, "capture error:%d, device:%s \n", result, devname);
|
||||||
|
}
|
||||||
|
if (mode != 1)
|
||||||
|
show_capture(devname);
|
||||||
|
else if (result > -1)
|
||||||
|
fprintf(stdout, "Capture of %s removed\n", devname);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
46
doc
46
doc
@@ -1,46 +0,0 @@
|
|||||||
/* DOC for NET.EXE */
|
|
||||||
This is a short description of net.exe which is a simple DOS-client
|
|
||||||
programm to allow standard NCP network actions, mainly for mars_nwe.
|
|
||||||
All functions are called as a second parameter.
|
|
||||||
This programm is very incomplete till now, but some functions
|
|
||||||
works well with mars_nwe.
|
|
||||||
|
|
||||||
LOGOUT:
|
|
||||||
Logout from a NCP Server.
|
|
||||||
|
|
||||||
LOGIN:
|
|
||||||
usage: LOGIN [-u] [user | user password]
|
|
||||||
-u = use unencrypted password.
|
|
||||||
With this function you can log into a NCP Server.
|
|
||||||
Its only make a login, no mappings or something else.
|
|
||||||
|
|
||||||
If you want a login similar to NOVELL's login.exe you should
|
|
||||||
do it with a batch job.
|
|
||||||
|
|
||||||
example:
|
|
||||||
[\LOGIN\LOGIN.BAT]
|
|
||||||
@echo OFF
|
|
||||||
net logout
|
|
||||||
net login %1 %2 %3
|
|
||||||
if errorlevel 1 goto :end
|
|
||||||
map h:=HOME:
|
|
||||||
if not exist h:\profile.bat goto :end
|
|
||||||
h:
|
|
||||||
profile.bat
|
|
||||||
:end
|
|
||||||
|
|
||||||
PASSWD:
|
|
||||||
usage: PASSWD [user]
|
|
||||||
With this function you are able to change a users password.
|
|
||||||
This call uses the old unencryted change password call !!
|
|
||||||
|
|
||||||
|
|
||||||
PATH:
|
|
||||||
usage: PATH sn:[=[path]]
|
|
||||||
sn = 's1' .. 's16'
|
|
||||||
|
|
||||||
With this function a new path element can be created.
|
|
||||||
Its only sets the path environment.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
93
doc/README
Executable file
93
doc/README
Executable file
@@ -0,0 +1,93 @@
|
|||||||
|
/* DOC for NET.EXE */
|
||||||
|
/* last updated: 21-May-96 */
|
||||||
|
This is a short description of net.exe which is a simple DOS-client
|
||||||
|
program to allow standard NCP network actions, mainly for mars_nwe.
|
||||||
|
All functions are called as a second parameter, or if the program
|
||||||
|
is renamed to a guilty function like login.exe then the function
|
||||||
|
will be the progname. This is very usefull for login.exe.
|
||||||
|
|
||||||
|
This program is very incomplete till now, but some functions
|
||||||
|
works well with mars_nwe.
|
||||||
|
|
||||||
|
|
||||||
|
LOGIN:
|
||||||
|
usage: LOGIN [-u] [user | user password]
|
||||||
|
-u = use unencrypted password.
|
||||||
|
With this function you can log into a NCP Server.
|
||||||
|
If there exists a 'login' file in the same directory as
|
||||||
|
net.exe resides then this file will be interpreted as a
|
||||||
|
command file. You also can use command files with
|
||||||
|
the PROFILE command.
|
||||||
|
It is usefull to copy (or do a Linux link) net.exe to login.exe.
|
||||||
|
|
||||||
|
example for a 'login' script (resides in same directory as net.exe)
|
||||||
|
|
||||||
|
map f:=SYS:
|
||||||
|
map h:=home:
|
||||||
|
map z:=SYS:PUBLIC
|
||||||
|
path s16:=z:.
|
||||||
|
capture lpt1 q1
|
||||||
|
profile h:\profile # will call users home 'profile'
|
||||||
|
|
||||||
|
if not exist h:\profile.bat goto :end
|
||||||
|
|
||||||
|
|
||||||
|
PROFILE:
|
||||||
|
usage: PROFILE filename
|
||||||
|
With this function you are able to run a command script.
|
||||||
|
In this command script you can use every net.exe command.
|
||||||
|
|
||||||
|
SPAWN:
|
||||||
|
With SPAWN you can start external programs.
|
||||||
|
|
||||||
|
PASSWD:
|
||||||
|
usage: PASSWD [user]
|
||||||
|
With this function you are able to change a users password.
|
||||||
|
This call uses the old unencryted change password call !!
|
||||||
|
|
||||||
|
PATH:
|
||||||
|
usage: PATH sn:[=[path]]
|
||||||
|
sn = 's1' .. 's16'
|
||||||
|
|
||||||
|
With this function a new path element can be created.
|
||||||
|
Its only sets the path environment !
|
||||||
|
|
||||||
|
PATHINS:
|
||||||
|
usage: PATHINS sn:[=[path]]
|
||||||
|
sn = 's1' .. 's16'
|
||||||
|
like PATH, but inserts PATH, not overwrites.
|
||||||
|
|
||||||
|
PATHDEL:
|
||||||
|
usage: PATHDEL sn:
|
||||||
|
sn = 's1' .. 's16'
|
||||||
|
deletes PATH element
|
||||||
|
|
||||||
|
MAP:
|
||||||
|
usage: MAP [d:[=[path]]]
|
||||||
|
d = 'A' .. 'Z'
|
||||||
|
Maps a drive to a volume or volume/path.
|
||||||
|
|
||||||
|
|
||||||
|
MAPDEL:
|
||||||
|
usage: MAPDEL d:
|
||||||
|
d = 'A' .. 'Z'
|
||||||
|
Removes a map.
|
||||||
|
|
||||||
|
|
||||||
|
LOGOUT:
|
||||||
|
Logout from a NCP Server.
|
||||||
|
|
||||||
|
DEBUG:
|
||||||
|
For setting debug flag in mars_nwe processes.
|
||||||
|
If you want to use this, you must set
|
||||||
|
mars_nwe/config.h: FUNC_17_02_IS_DEBUG to '1'
|
||||||
|
|
||||||
|
|
||||||
|
SPAWN:
|
||||||
|
EXEC:
|
||||||
|
external program execution spawning or overlayed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0
kern.asm → doc/kern.asm
Executable file → Normal file
0
kern.asm → doc/kern.asm
Executable file → Normal file
2
makefile → doc/makefile.bcc
Executable file → Normal file
2
makefile → doc/makefile.bcc
Executable file → Normal file
@@ -21,7 +21,7 @@ RM = del
|
|||||||
ASMODS= kern$(O)
|
ASMODS= kern$(O)
|
||||||
CCMODS= tools$(O) netcall$(O) ncpcall$(O) \
|
CCMODS= tools$(O) netcall$(O) ncpcall$(O) \
|
||||||
login$(O) map$(O) slist$(O) nwcrypt$(O) \
|
login$(O) map$(O) slist$(O) nwcrypt$(O) \
|
||||||
nwdebug$(O) nwtests$(O)
|
nwdebug$(O) nwtests$(O) capture$(O)
|
||||||
|
|
||||||
all: net$(E)
|
all: net$(E)
|
||||||
|
|
||||||
16
doc/mars_dosutils.lsm
Normal file
16
doc/mars_dosutils.lsm
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Begin3
|
||||||
|
Title: mars_dosutils
|
||||||
|
Version: 0.10
|
||||||
|
Entered-date: 21-May-96
|
||||||
|
|
||||||
|
Description: Simple DOS client program specially
|
||||||
|
for mars_nwe.
|
||||||
|
Supports login, map, capture, passwd
|
||||||
|
Binary + sourcen
|
||||||
|
Keywords: novell, netware, client, ipx, ncp, mars_nwe
|
||||||
|
Author: mstover@freeway.de (Martin Stover)
|
||||||
|
Maintained-by: mstover@freeway.de (Martin Stover)
|
||||||
|
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
|
||||||
|
60kB mars_dosutils-0.10.tgz
|
||||||
|
Platforms: DOS, DOSEMU
|
||||||
|
End
|
||||||
474
flag.c
Normal file
474
flag.c
Normal file
@@ -0,0 +1,474 @@
|
|||||||
|
/* flag.c - Novell FLAG-like DOS utility, stage 1 */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FLAG v4b: NCP 87 namespace DOS info.
|
||||||
|
*
|
||||||
|
* ncpfs reference:
|
||||||
|
* ncp_ns_modify_entry_dos_info():
|
||||||
|
* subfunction 7, namespace DOS, search attrs SA_ALL,
|
||||||
|
* ModifyInformationMask, struct ncp_dos_info, handle/path.
|
||||||
|
*
|
||||||
|
* We use dirstyle=0 (short directory handle) against the current DOS
|
||||||
|
* directory handle and a one-component DOS filename.
|
||||||
|
*/
|
||||||
|
#define FLAG_NW_NS_DOS 0x00
|
||||||
|
#define FLAG_SA_ALL 0x0006
|
||||||
|
#define FLAG_RIM_ATTRIBUTES 0x00000004UL
|
||||||
|
|
||||||
|
#define NWFA_RO 0x00000001UL
|
||||||
|
#define NWFA_H 0x00000002UL
|
||||||
|
#define NWFA_SY 0x00000004UL
|
||||||
|
#define NWFA_A 0x00000020UL
|
||||||
|
#define NWFA_S 0x00000080UL
|
||||||
|
#define NWFA_T 0x00001000UL
|
||||||
|
#define NWFA_RA 0x00004000UL
|
||||||
|
#define NWFA_WA 0x00008000UL
|
||||||
|
#define NWFA_P 0x00010000UL
|
||||||
|
#define NWFA_RI 0x00020000UL
|
||||||
|
#define NWFA_DI 0x00040000UL
|
||||||
|
#define NWFA_CI 0x00080000UL
|
||||||
|
|
||||||
|
static void flag_put_word_lh(uint8 *p, uint16 v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8)(v & 0xff);
|
||||||
|
p[1] = (uint8)((v >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flag_put_dword_lh(uint8 *p, uint32 v)
|
||||||
|
{
|
||||||
|
p[0] = (uint8)(v & 0xff);
|
||||||
|
p[1] = (uint8)((v >> 8) & 0xff);
|
||||||
|
p[2] = (uint8)((v >> 16) & 0xff);
|
||||||
|
p[3] = (uint8)((v >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 flag_get_dword_lh(uint8 *p)
|
||||||
|
{
|
||||||
|
return((uint32)p[0] |
|
||||||
|
((uint32)p[1] << 8) |
|
||||||
|
((uint32)p[2] << 16) |
|
||||||
|
((uint32)p[3] << 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_add_handle_path(uint8 *p, uint8 dhandle, char *name)
|
||||||
|
{
|
||||||
|
int nlen;
|
||||||
|
|
||||||
|
nlen = strlen(name);
|
||||||
|
if (nlen > 255) nlen = 255;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle/path:
|
||||||
|
* volume/handle byte
|
||||||
|
* dir base dword
|
||||||
|
* dirstyle byte (0 = short dir handle)
|
||||||
|
* path components: 1 component, length, bytes
|
||||||
|
*/
|
||||||
|
*p++ = dhandle;
|
||||||
|
flag_put_dword_lh(p, 0L); p += 4;
|
||||||
|
*p++ = 0; /* dirstyle = handle */
|
||||||
|
*p++ = 1; /* one path component */
|
||||||
|
*p++ = (uint8)nlen;
|
||||||
|
memcpy(p, name, nlen);
|
||||||
|
p += nlen;
|
||||||
|
|
||||||
|
return(1 + 4 + 1 + 1 + 1 + nlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_ncp87_obtain_attrs(char *name, uint32 *attrs)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 data[320];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 data[128];
|
||||||
|
} repl;
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint8 *p;
|
||||||
|
int hlen;
|
||||||
|
|
||||||
|
if (tool_current_dhandle(&connid, &dhandle))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prefer the verified Client32 NCP87 path. If it is not available,
|
||||||
|
* fall back to the historical INT 21h/Net_Call path below.
|
||||||
|
*/
|
||||||
|
if (c32_ncp87_obtain_rim_attributes(name, (uint16)dhandle,
|
||||||
|
attrs, NULL, NULL, NULL) == 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
p = req.data;
|
||||||
|
*p++ = 6; /* subfunction: obtain file/subdir info */
|
||||||
|
*p++ = FLAG_NW_NS_DOS; /* source namespace */
|
||||||
|
*p++ = FLAG_NW_NS_DOS; /* target namespace */
|
||||||
|
flag_put_word_lh(p, FLAG_SA_ALL); p += 2;
|
||||||
|
flag_put_dword_lh(p, FLAG_RIM_ATTRIBUTES); p += 4;
|
||||||
|
hlen = flag_add_handle_path(p, dhandle, name);
|
||||||
|
p += hlen;
|
||||||
|
|
||||||
|
req.len = (uint16)(p - req.data);
|
||||||
|
repl.len = sizeof(repl.data);
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xF257, &req, &repl);
|
||||||
|
if (neterrno)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With RIM_ATTRIBUTES only, ncpfs expects NSI_Attributes first.
|
||||||
|
* First dword is the 32-bit Attributes field.
|
||||||
|
*/
|
||||||
|
if (attrs)
|
||||||
|
*attrs = flag_get_dword_lh(repl.data);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_ncp87_modify_attrs(char *name, uint32 attrs)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 data[384];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 data[8];
|
||||||
|
} repl;
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint8 *p;
|
||||||
|
int hlen;
|
||||||
|
|
||||||
|
if (tool_current_dhandle(&connid, &dhandle))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prefer verified Client32 modify path. The old INT 21h/F257 modify path
|
||||||
|
* can hang under DOS Client32 for high FLAG bits such as T/P/DI/RI.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
uint16 actual = 0;
|
||||||
|
uint16 hlo = 0;
|
||||||
|
uint16 hhi = 0;
|
||||||
|
if (!c32_ncp87_modify_dos_attributes(name, (uint16)dhandle, attrs,
|
||||||
|
&actual, &hlo, &hhi))
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
p = req.data;
|
||||||
|
*p++ = 7; /* subfunction: modify DOS info */
|
||||||
|
*p++ = FLAG_NW_NS_DOS;
|
||||||
|
*p++ = 0; /* reserved */
|
||||||
|
flag_put_word_lh(p, FLAG_SA_ALL); p += 2;
|
||||||
|
|
||||||
|
flag_put_dword_lh(p, FLAG_RIM_ATTRIBUTES); p += 4; /* modify mask */
|
||||||
|
flag_put_dword_lh(p, attrs); p += 4; /* Attributes */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remaining ncp_dos_info fields. Mask says only Attributes is valid,
|
||||||
|
* so these should be ignored, but ncpfs still sends the full structure.
|
||||||
|
*/
|
||||||
|
memset(p, 0, 34);
|
||||||
|
p += 34;
|
||||||
|
|
||||||
|
hlen = flag_add_handle_path(p, dhandle, name);
|
||||||
|
p += hlen;
|
||||||
|
|
||||||
|
req.len = (uint16)(p - req.data);
|
||||||
|
repl.len = sizeof(repl.data);
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xF257, &req, &repl);
|
||||||
|
if (neterrno)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _A_NORMAL
|
||||||
|
#define _A_NORMAL 0x00
|
||||||
|
#endif
|
||||||
|
#ifndef _A_RDONLY
|
||||||
|
#define _A_RDONLY 0x01
|
||||||
|
#endif
|
||||||
|
#ifndef _A_HIDDEN
|
||||||
|
#define _A_HIDDEN 0x02
|
||||||
|
#endif
|
||||||
|
#ifndef _A_SYSTEM
|
||||||
|
#define _A_SYSTEM 0x04
|
||||||
|
#endif
|
||||||
|
#ifndef _A_SUBDIR
|
||||||
|
#define _A_SUBDIR 0x10
|
||||||
|
#endif
|
||||||
|
#ifndef _A_ARCH
|
||||||
|
#define _A_ARCH 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void flag_help(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "USAGE: FLAG [path [ option | [+|-] attribute(s) ] [SUB]]\n");
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, "386 Attributes:\n");
|
||||||
|
fprintf(stdout, "--------------\n");
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, "RO Read Only\n");
|
||||||
|
fprintf(stdout, "RW Read Write\n");
|
||||||
|
fprintf(stdout, "S Sharable\n");
|
||||||
|
fprintf(stdout, "H Hidden\n");
|
||||||
|
fprintf(stdout, "Sy System\n");
|
||||||
|
fprintf(stdout, "T Transactional\n");
|
||||||
|
fprintf(stdout, "P Purge\n");
|
||||||
|
fprintf(stdout, "A Archive Needed\n");
|
||||||
|
fprintf(stdout, "RA Read Audit\n");
|
||||||
|
fprintf(stdout, "WA Write Audit\n");
|
||||||
|
fprintf(stdout, "CI Copy Inhibit\n");
|
||||||
|
fprintf(stdout, "DI Delete Inhibit\n");
|
||||||
|
fprintf(stdout, "RI Rename Inhibit\n");
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, "All All\n");
|
||||||
|
fprintf(stdout, "N Normal\n");
|
||||||
|
fprintf(stdout, "SUB\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_attr_mask(char *s, uint32 *setbits, uint32 *clearbits)
|
||||||
|
{
|
||||||
|
int set = 1;
|
||||||
|
char *p = s;
|
||||||
|
|
||||||
|
if (*p == '+') {
|
||||||
|
set = 1;
|
||||||
|
p++;
|
||||||
|
} else if (*p == '-') {
|
||||||
|
set = 0;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*p) return(-1);
|
||||||
|
|
||||||
|
if (tool_strsame(p, "RO")) {
|
||||||
|
if (set) {
|
||||||
|
*setbits |= (NWFA_RO | NWFA_DI | NWFA_RI);
|
||||||
|
} else {
|
||||||
|
*clearbits |= (NWFA_RO | NWFA_DI | NWFA_RI);
|
||||||
|
}
|
||||||
|
} else if (tool_strsame(p, "RW")) {
|
||||||
|
*clearbits |= (NWFA_RO | NWFA_DI | NWFA_RI);
|
||||||
|
} else if (tool_strsame(p, "S")) {
|
||||||
|
if (set) *setbits |= NWFA_S;
|
||||||
|
else *clearbits |= NWFA_S;
|
||||||
|
} else if (tool_strsame(p, "H")) {
|
||||||
|
if (set) *setbits |= NWFA_H;
|
||||||
|
else *clearbits |= NWFA_H;
|
||||||
|
} else if (tool_strsame(p, "SY") || tool_strsame(p, "SYS") || tool_strsame(p, "SYSTEM")) {
|
||||||
|
if (set) *setbits |= NWFA_SY;
|
||||||
|
else *clearbits |= NWFA_SY;
|
||||||
|
} else if (tool_strsame(p, "T")) {
|
||||||
|
if (set) *setbits |= NWFA_T;
|
||||||
|
else *clearbits |= NWFA_T;
|
||||||
|
} else if (tool_strsame(p, "P")) {
|
||||||
|
if (set) *setbits |= NWFA_P;
|
||||||
|
else *clearbits |= NWFA_P;
|
||||||
|
} else if (tool_strsame(p, "A")) {
|
||||||
|
if (set) *setbits |= NWFA_A;
|
||||||
|
else *clearbits |= NWFA_A;
|
||||||
|
} else if (tool_strsame(p, "RA")) {
|
||||||
|
if (set) *setbits |= NWFA_RA;
|
||||||
|
else *clearbits |= NWFA_RA;
|
||||||
|
} else if (tool_strsame(p, "WA")) {
|
||||||
|
if (set) *setbits |= NWFA_WA;
|
||||||
|
else *clearbits |= NWFA_WA;
|
||||||
|
} else if (tool_strsame(p, "CI")) {
|
||||||
|
if (set) *setbits |= NWFA_CI;
|
||||||
|
else *clearbits |= NWFA_CI;
|
||||||
|
} else if (tool_strsame(p, "DI")) {
|
||||||
|
if (set) *setbits |= NWFA_DI;
|
||||||
|
else *clearbits |= NWFA_DI;
|
||||||
|
} else if (tool_strsame(p, "RI")) {
|
||||||
|
if (set) *setbits |= NWFA_RI;
|
||||||
|
else *clearbits |= NWFA_RI;
|
||||||
|
} else if (tool_strsame(p, "N") || tool_strsame(p, "NORMAL")) {
|
||||||
|
*clearbits |= (NWFA_RO | NWFA_H | NWFA_SY | NWFA_A |
|
||||||
|
NWFA_S | NWFA_T | NWFA_P |
|
||||||
|
NWFA_RA | NWFA_WA | NWFA_CI | NWFA_DI | NWFA_RI);
|
||||||
|
} else if (tool_strsame(p, "ALL")) {
|
||||||
|
*setbits |= (NWFA_RO | NWFA_H | NWFA_SY | NWFA_A |
|
||||||
|
NWFA_S | NWFA_T | NWFA_P |
|
||||||
|
NWFA_RA | NWFA_WA | NWFA_CI | NWFA_DI | NWFA_RI);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unknown attribute encountered in command line.\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flag_print_attrs(uint32 attr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Novell order:
|
||||||
|
* Ro/Rw S A - H Sy T P Ra Wa CI DI RI
|
||||||
|
*/
|
||||||
|
fprintf(stdout, "[ ");
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_RO) ? "Ro" : "Rw");
|
||||||
|
fprintf(stdout, "%c ", (attr & NWFA_S) ? 'S' : '-');
|
||||||
|
fprintf(stdout, "%c ", (attr & NWFA_A) ? 'A' : '-');
|
||||||
|
fprintf(stdout, "- ");
|
||||||
|
fprintf(stdout, "%c ", (attr & NWFA_H) ? 'H' : '-');
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_SY) ? "Sy" : "--");
|
||||||
|
fprintf(stdout, "%c ", (attr & NWFA_T) ? 'T' : '-');
|
||||||
|
fprintf(stdout, "%c ", (attr & NWFA_P) ? 'P' : '-');
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_RA) ? "Ra" : "--");
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_WA) ? "Wa" : "--");
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_CI) ? "CI" : "--");
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_DI) ? "DI" : "--");
|
||||||
|
fprintf(stdout, "%s ", (attr & NWFA_RI) ? "RI" : "--");
|
||||||
|
fprintf(stdout, "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flag_display_one(char *name, uint32 attr)
|
||||||
|
{
|
||||||
|
fprintf(stdout, " %-23s ", name);
|
||||||
|
flag_print_attrs(attr);
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flag_display_one_paged(char *name, uint32 attr,
|
||||||
|
int *line_count, int *continuous)
|
||||||
|
{
|
||||||
|
flag_display_one(name, attr);
|
||||||
|
tool_page_line(line_count, continuous);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int flag_list(char *pattern)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
unsigned findattr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH;
|
||||||
|
int found = 0;
|
||||||
|
int line_count = 0;
|
||||||
|
int continuous = 0;
|
||||||
|
|
||||||
|
if (_dos_findfirst(pattern, findattr, &ff))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!(ff.attrib & _A_SUBDIR)) {
|
||||||
|
uint32 nwattrs;
|
||||||
|
|
||||||
|
if (flag_ncp87_obtain_attrs(ff.name, &nwattrs))
|
||||||
|
nwattrs = (uint32)ff.attrib;
|
||||||
|
|
||||||
|
flag_display_one_paged(ff.name, nwattrs, &line_count, &continuous);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
} while (!_dos_findnext(&ff));
|
||||||
|
|
||||||
|
return(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_apply(char *pattern, uint32 setbits, uint32 clearbits)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
unsigned findattr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH;
|
||||||
|
int shown = 0;
|
||||||
|
|
||||||
|
if (_dos_findfirst(pattern, findattr, &ff))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint32 attrs;
|
||||||
|
uint32 newattrs;
|
||||||
|
char fname[260];
|
||||||
|
|
||||||
|
if (ff.attrib & _A_SUBDIR) continue;
|
||||||
|
|
||||||
|
strmaxcpy(fname, ff.name, sizeof(fname) - 1);
|
||||||
|
|
||||||
|
if (flag_ncp87_obtain_attrs(fname, &attrs))
|
||||||
|
attrs = (uint32)ff.attrib;
|
||||||
|
|
||||||
|
newattrs = (attrs | (uint32)setbits) & ~((uint32)clearbits);
|
||||||
|
|
||||||
|
if (newattrs != attrs) {
|
||||||
|
if (flag_ncp87_modify_attrs(fname, newattrs)) {
|
||||||
|
unsigned dosattr = (newattrs & (_A_RDONLY|_A_HIDDEN|_A_SYSTEM|_A_ARCH));
|
||||||
|
if (_dos_setfileattr(fname, dosattr)) {
|
||||||
|
fprintf(stderr, "You don't have rights to change : %s\n", fname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag_ncp87_obtain_attrs(fname, &attrs))
|
||||||
|
attrs = newattrs;
|
||||||
|
|
||||||
|
flag_display_one(fname, newattrs);
|
||||||
|
shown++;
|
||||||
|
|
||||||
|
} while (!_dos_findnext(&ff));
|
||||||
|
|
||||||
|
return(shown);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_flag(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
char *path = "*.*";
|
||||||
|
int i;
|
||||||
|
uint32 setbits = 0;
|
||||||
|
uint32 clearbits = 0;
|
||||||
|
int have_change = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc > 1 && (tool_strsame(argv[1], "/?") || tool_strsame(argv[1], "-?") ||
|
||||||
|
tool_strsame(argv[1], "?"))) {
|
||||||
|
flag_help();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
path = argv[1];
|
||||||
|
if (tool_strsame(path, "SUB")) path = "*.*";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
if (tool_strsame(argv[i], "SUB")) continue;
|
||||||
|
|
||||||
|
rc = flag_attr_mask(argv[i], &setbits, &clearbits);
|
||||||
|
if (rc < 0) return(1);
|
||||||
|
if (rc > 0) continue;
|
||||||
|
have_change = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_change) {
|
||||||
|
rc = flag_apply(path, setbits, clearbits);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "Files could not be found with pattern \"%s\"\n", path);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = flag_list(path);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "Files could not be found with pattern \"%s\"\n", path);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
321
flagdir.c
Normal file
321
flagdir.c
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
/* flagdir.c - Novell FLAGDIR-like DOS utility, Client32 version */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
#define FD_NWFA_H 0x00000002UL
|
||||||
|
#define FD_NWFA_SY 0x00000004UL
|
||||||
|
#define FD_NWFA_P 0x00010000UL
|
||||||
|
#define FD_NWFA_RI 0x00020000UL
|
||||||
|
#define FD_NWFA_DI 0x00040000UL
|
||||||
|
|
||||||
|
#define FD_DIR_BITS (FD_NWFA_H | FD_NWFA_SY | FD_NWFA_P | FD_NWFA_RI | FD_NWFA_DI)
|
||||||
|
|
||||||
|
#ifndef _A_RDONLY
|
||||||
|
#define _A_RDONLY 0x01
|
||||||
|
#endif
|
||||||
|
#ifndef _A_HIDDEN
|
||||||
|
#define _A_HIDDEN 0x02
|
||||||
|
#endif
|
||||||
|
#ifndef _A_SYSTEM
|
||||||
|
#define _A_SYSTEM 0x04
|
||||||
|
#endif
|
||||||
|
#ifndef _A_SUBDIR
|
||||||
|
#define _A_SUBDIR 0x10
|
||||||
|
#endif
|
||||||
|
#ifndef _A_ARCH
|
||||||
|
#define _A_ARCH 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int fd_current_display_path(uint8 dhandle, char *out, int max)
|
||||||
|
{
|
||||||
|
char path[260];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!out || max < 2)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
out[0] = '\0';
|
||||||
|
path[0] = '\0';
|
||||||
|
|
||||||
|
if (get_dir_path(dhandle, path) || !path[0])
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
p = strchr(path, ':');
|
||||||
|
if (p)
|
||||||
|
p++;
|
||||||
|
else
|
||||||
|
p = path;
|
||||||
|
|
||||||
|
if (!*p)
|
||||||
|
out[0] = '\0';
|
||||||
|
else
|
||||||
|
strmaxcpy(out, p, max - 1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fd_help(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "386 Usage: Flagdir [path [option...]]\n");
|
||||||
|
fprintf(stdout, "Options: Normal\n");
|
||||||
|
fprintf(stdout, " System\n");
|
||||||
|
fprintf(stdout, " Hidden\n");
|
||||||
|
fprintf(stdout, " Deleteinhibit\n");
|
||||||
|
fprintf(stdout, " Purge\n");
|
||||||
|
fprintf(stdout, " Renameinhibit\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_attr_mask(char *s, uint32 *setbits, uint32 *clearbits)
|
||||||
|
{
|
||||||
|
if (tool_strsame(s, "N") || tool_strsame(s, "NORMAL")) {
|
||||||
|
*clearbits |= FD_DIR_BITS;
|
||||||
|
} else if (tool_strsame(s, "S") || tool_strsame(s, "SY") ||
|
||||||
|
tool_strsame(s, "SYS") || tool_strsame(s, "SYSTEM")) {
|
||||||
|
*setbits |= FD_NWFA_SY;
|
||||||
|
} else if (tool_strsame(s, "H") || tool_strsame(s, "HIDDEN")) {
|
||||||
|
*setbits |= FD_NWFA_H;
|
||||||
|
} else if (tool_strsame(s, "DI") || tool_strsame(s, "DELETEINHIBIT")) {
|
||||||
|
*setbits |= FD_NWFA_DI;
|
||||||
|
} else if (tool_strsame(s, "P") || tool_strsame(s, "PURGE")) {
|
||||||
|
*setbits |= FD_NWFA_P;
|
||||||
|
} else if (tool_strsame(s, "RI") || tool_strsame(s, "RENAMEINHIBIT")) {
|
||||||
|
*setbits |= FD_NWFA_RI;
|
||||||
|
} else if (tool_strsame(s, "PRIVATE") || tool_strsame(s, "PR")) {
|
||||||
|
fprintf(stderr, "Private is valid on NetWare 2.15 and above, except NetWare 386.\n");
|
||||||
|
return(-1);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unknown attribute: %s.\n", s);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fd_print_attrs(uint32 attrs)
|
||||||
|
{
|
||||||
|
int any = 0;
|
||||||
|
|
||||||
|
if (!(attrs & FD_DIR_BITS)) {
|
||||||
|
fprintf(stdout, "Normal\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs & FD_NWFA_SY) {
|
||||||
|
fprintf(stdout, "System");
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
if (attrs & FD_NWFA_H) {
|
||||||
|
fprintf(stdout, "%sHidden", any ? " " : "");
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
if (attrs & FD_NWFA_DI) {
|
||||||
|
fprintf(stdout, "%sDeleteInhibit", any ? " " : "");
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
if (attrs & FD_NWFA_P) {
|
||||||
|
fprintf(stdout, "%sPurge", any ? " " : "");
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
if (attrs & FD_NWFA_RI) {
|
||||||
|
fprintf(stdout, "%sRenameInhibit", any ? " " : "");
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fd_display_header(char *path)
|
||||||
|
{
|
||||||
|
char up[260];
|
||||||
|
char prefix[90];
|
||||||
|
|
||||||
|
tool_upcopy(up, path, sizeof(up));
|
||||||
|
|
||||||
|
if (tool_current_prefix(prefix, sizeof(prefix)))
|
||||||
|
prefix[0] = '\0';
|
||||||
|
|
||||||
|
fprintf(stdout, "%s%s \n", prefix, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fd_display_row(char *name, uint32 attrs)
|
||||||
|
{
|
||||||
|
char base[260];
|
||||||
|
|
||||||
|
tool_basename(base, name, sizeof(base));
|
||||||
|
fprintf(stdout, " %-12.12s ", base);
|
||||||
|
fd_print_attrs(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fd_display(char *path, uint32 attrs)
|
||||||
|
{
|
||||||
|
fd_display_header(path);
|
||||||
|
fd_display_row(path, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_is_directory(char *path)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
unsigned attr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR | _A_ARCH;
|
||||||
|
|
||||||
|
if (tool_is_current_path(path))
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
if (_dos_findfirst(path, attr, &ff))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
return((ff.attrib & _A_SUBDIR) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_obtain(char *path, uint8 dhandle, uint32 *attrs)
|
||||||
|
{
|
||||||
|
if (c32_ncp87_obtain_rim_attributes(path, (uint16)dhandle,
|
||||||
|
attrs, NULL, NULL, NULL) == 0)
|
||||||
|
return(0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_modify(char *path, uint8 dhandle, uint32 attrs)
|
||||||
|
{
|
||||||
|
if (c32_ncp87_modify_dos_attributes(path, (uint16)dhandle, attrs,
|
||||||
|
NULL, NULL, NULL) == 0)
|
||||||
|
return(0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_process_one(char *path, char *display_path, uint8 dhandle,
|
||||||
|
uint32 setbits, uint32 clearbits,
|
||||||
|
int have_change, int show_header)
|
||||||
|
{
|
||||||
|
char *ncp_path;
|
||||||
|
uint32 attrs;
|
||||||
|
uint32 newattrs;
|
||||||
|
|
||||||
|
if (!fd_is_directory(path)) {
|
||||||
|
fprintf(stderr, "Directory %s not found.\n", path);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ncp_path = tool_is_current_path(path) ? "" : path;
|
||||||
|
|
||||||
|
if (fd_obtain(ncp_path, dhandle, &attrs)) {
|
||||||
|
if (tool_is_current_path(path) && display_path && !display_path[0] &&
|
||||||
|
!have_change) {
|
||||||
|
attrs = 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unable to get directory attributes.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_change) {
|
||||||
|
newattrs = (attrs | setbits) & ~clearbits;
|
||||||
|
if (newattrs != attrs) {
|
||||||
|
if (fd_modify(ncp_path, dhandle, newattrs)) {
|
||||||
|
fprintf(stderr, "Unable to change attributes.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
attrs = newattrs;
|
||||||
|
fd_obtain(ncp_path, dhandle, &attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_header)
|
||||||
|
fd_display(display_path, attrs);
|
||||||
|
else
|
||||||
|
fd_display_row(display_path, attrs);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_process_wild(char *spec, uint8 dhandle,
|
||||||
|
uint32 setbits, uint32 clearbits,
|
||||||
|
int have_change)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char dir[260];
|
||||||
|
char pat[260];
|
||||||
|
char search[260];
|
||||||
|
char full[260];
|
||||||
|
int found = 0;
|
||||||
|
int rc = 0;
|
||||||
|
int lines = 0;
|
||||||
|
int continuous = 0;
|
||||||
|
unsigned attr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR | _A_ARCH;
|
||||||
|
|
||||||
|
tool_parent_pattern(dir, pat, spec, sizeof(dir), sizeof(pat));
|
||||||
|
tool_join_path(search, dir, pat, sizeof(search));
|
||||||
|
|
||||||
|
if (_dos_findfirst(search, attr, &ff) != 0) {
|
||||||
|
fprintf(stderr, "Directory %s not found.\n", spec);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_display_header(spec);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((ff.attrib & _A_SUBDIR) && strcmp(ff.name, ".") &&
|
||||||
|
strcmp(ff.name, "..")) {
|
||||||
|
tool_join_path(full, dir, ff.name, sizeof(full));
|
||||||
|
if (fd_process_one(full, ff.name, dhandle, setbits, clearbits,
|
||||||
|
have_change, 0))
|
||||||
|
rc = 1;
|
||||||
|
found++;
|
||||||
|
tool_page_line(&lines, &continuous);
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
fprintf(stderr, "Directory %s not found.\n", spec);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_flagdir(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
char *path = ".";
|
||||||
|
char display_path[260];
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint32 setbits = 0;
|
||||||
|
uint32 clearbits = 0;
|
||||||
|
int have_change = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc > 1 && (tool_strsame(argv[1], "/?") || tool_strsame(argv[1], "-?") ||
|
||||||
|
tool_strsame(argv[1], "?"))) {
|
||||||
|
fd_help();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
path = argv[1];
|
||||||
|
|
||||||
|
if (tool_current_dhandle(&connid, &dhandle)) {
|
||||||
|
fprintf(stderr, "FlagDir only works on network directories.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
if (fd_attr_mask(argv[i], &setbits, &clearbits))
|
||||||
|
return(1);
|
||||||
|
have_change = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_has_wildcards(path))
|
||||||
|
return(fd_process_wild(path, dhandle, setbits, clearbits, have_change));
|
||||||
|
|
||||||
|
if (tool_is_current_path(path)) {
|
||||||
|
if (fd_current_display_path(dhandle, display_path, sizeof(display_path)))
|
||||||
|
strcpy(display_path, ".");
|
||||||
|
} else {
|
||||||
|
strmaxcpy(display_path, path, sizeof(display_path) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(fd_process_one(path, display_path, dhandle,
|
||||||
|
setbits, clearbits, have_change, 1));
|
||||||
|
}
|
||||||
345
grant.c
Normal file
345
grant.c
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
/* grant.c - Novell GRANT-like DOS utility, first Client32 implementation */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
|
||||||
|
#define GRANT_BINDERY_USER 0x0001
|
||||||
|
#define GRANT_BINDERY_GROUP 0x0002
|
||||||
|
|
||||||
|
#define NCP_RIGHT_READ 0x0001
|
||||||
|
#define NCP_RIGHT_WRITE 0x0002
|
||||||
|
#define NCP_RIGHT_OPEN 0x0004
|
||||||
|
#define NCP_RIGHT_CREATE 0x0008
|
||||||
|
#define NCP_RIGHT_DELETE 0x0010
|
||||||
|
#define NCP_RIGHT_OWNER 0x0020
|
||||||
|
#define NCP_RIGHT_SEARCH 0x0040
|
||||||
|
#define NCP_RIGHT_MODIFY 0x0080
|
||||||
|
#define NCP_RIGHT_SUPER 0x0100
|
||||||
|
|
||||||
|
/* Novell GRANT ALL assigns all normal trustee rights, not Supervisor. */
|
||||||
|
#define NCP_RIGHT_ALL_386 (NCP_RIGHT_READ | NCP_RIGHT_WRITE | \
|
||||||
|
NCP_RIGHT_CREATE | NCP_RIGHT_DELETE | \
|
||||||
|
NCP_RIGHT_MODIFY | NCP_RIGHT_SEARCH | \
|
||||||
|
NCP_RIGHT_OWNER)
|
||||||
|
|
||||||
|
static void grant_usage_error(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Command line arguments violate grammar defined for GRANT.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void grant_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Usage: GRANT rightslist* [FOR path] TO [USER | GROUP] name [options]\n");
|
||||||
|
fprintf(stdout, "Options: /SubDirectories | /Files\n\n");
|
||||||
|
fprintf(stdout, "386 Rights:\n");
|
||||||
|
fprintf(stdout, "--------------------\n");
|
||||||
|
fprintf(stdout, "ALL = All\n");
|
||||||
|
fprintf(stdout, "N = No Rights\n");
|
||||||
|
fprintf(stdout, "S = Supervisor\n");
|
||||||
|
fprintf(stdout, "R = Read\n");
|
||||||
|
fprintf(stdout, "W = Write\n");
|
||||||
|
fprintf(stdout, "C = Create\n");
|
||||||
|
fprintf(stdout, "E = Erase\n");
|
||||||
|
fprintf(stdout, "M = Modify\n");
|
||||||
|
fprintf(stdout, "F = File Scan\n");
|
||||||
|
fprintf(stdout, "A = Access Control\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void grant_rights_bracket(uint16 rights, char *out)
|
||||||
|
{
|
||||||
|
out[0] = (rights & NCP_RIGHT_SUPER) ? 'S' : ' ';
|
||||||
|
out[1] = (rights & NCP_RIGHT_READ) ? 'R' : ' ';
|
||||||
|
out[2] = (rights & NCP_RIGHT_WRITE) ? 'W' : ' ';
|
||||||
|
out[3] = (rights & NCP_RIGHT_CREATE) ? 'C' : ' ';
|
||||||
|
out[4] = (rights & NCP_RIGHT_DELETE) ? 'E' : ' ';
|
||||||
|
out[5] = (rights & NCP_RIGHT_MODIFY) ? 'M' : ' ';
|
||||||
|
out[6] = (rights & NCP_RIGHT_SEARCH) ? 'F' : ' ';
|
||||||
|
out[7] = (rights & NCP_RIGHT_OWNER) ? 'A' : ' ';
|
||||||
|
out[8] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void grant_rights_string(uint16 rights, char *out)
|
||||||
|
{
|
||||||
|
char *p = out;
|
||||||
|
|
||||||
|
if (rights == 0) {
|
||||||
|
strcpy(out, "N");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rights & NCP_RIGHT_ALL_386) == NCP_RIGHT_ALL_386) {
|
||||||
|
strcpy(out, "ALL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rights & NCP_RIGHT_SUPER) *p++ = 'S';
|
||||||
|
if (rights & NCP_RIGHT_READ) *p++ = 'R';
|
||||||
|
if (rights & NCP_RIGHT_WRITE) *p++ = 'W';
|
||||||
|
if (rights & NCP_RIGHT_CREATE) *p++ = 'C';
|
||||||
|
if (rights & NCP_RIGHT_DELETE) *p++ = 'E';
|
||||||
|
if (rights & NCP_RIGHT_MODIFY) *p++ = 'M';
|
||||||
|
if (rights & NCP_RIGHT_SEARCH) *p++ = 'F';
|
||||||
|
if (rights & NCP_RIGHT_OWNER) *p++ = 'A';
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int grant_add_right_word(char *s, uint16 *rights)
|
||||||
|
{
|
||||||
|
if (tool_strsame(s, "ALL")) {
|
||||||
|
*rights = NCP_RIGHT_ALL_386;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "N") || tool_strsame(s, "NONE")) {
|
||||||
|
*rights = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "S") || tool_strsame(s, "SUPERVISOR")) {
|
||||||
|
*rights |= NCP_RIGHT_SUPER;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "R") || tool_strsame(s, "READ")) {
|
||||||
|
*rights |= NCP_RIGHT_READ;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "W") || tool_strsame(s, "WRITE")) {
|
||||||
|
*rights |= NCP_RIGHT_WRITE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "C") || tool_strsame(s, "CREATE")) {
|
||||||
|
*rights |= NCP_RIGHT_CREATE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "E") || tool_strsame(s, "ERASE")) {
|
||||||
|
*rights |= NCP_RIGHT_DELETE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "M") || tool_strsame(s, "MODIFY")) {
|
||||||
|
*rights |= NCP_RIGHT_MODIFY;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "F") || tool_strsame(s, "FILESCAN") ||
|
||||||
|
tool_strsame(s, "FILE") || tool_strsame(s, "SCAN")) {
|
||||||
|
*rights |= NCP_RIGHT_SEARCH;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(s, "A") || tool_strsame(s, "ACCESS") ||
|
||||||
|
tool_strsame(s, "CONTROL") || tool_strsame(s, "ACCESSCONTROL")) {
|
||||||
|
*rights |= NCP_RIGHT_OWNER;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int grant_last_rc = 0;
|
||||||
|
|
||||||
|
static int grant_set_one(char *path, uint16 dhandle,
|
||||||
|
uint32 object_id, uint16 rights)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = c32_ncp87_add_trustee_rights(path,
|
||||||
|
dhandle,
|
||||||
|
object_id,
|
||||||
|
rights,
|
||||||
|
0xffff,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
grant_last_rc = rc;
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply the grant to PATH and every directory below it.
|
||||||
|
*
|
||||||
|
* This intentionally walks through the DOS redirector, not through another
|
||||||
|
* NCP search helper, so it works with the same mapped-drive view that the
|
||||||
|
* user passed to GRANT.
|
||||||
|
*/
|
||||||
|
static int grant_set_subdirs(char *path, uint16 dhandle,
|
||||||
|
uint32 object_id, uint16 rights)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char pattern[260];
|
||||||
|
char child[260];
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (grant_set_one(path, dhandle, object_id, rights))
|
||||||
|
rc = 1;
|
||||||
|
|
||||||
|
tool_join_path(pattern, path, "*.*", sizeof(pattern));
|
||||||
|
|
||||||
|
if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) {
|
||||||
|
do {
|
||||||
|
if ((ff.attrib & _A_SUBDIR) && !tool_is_dot_dir(ff.name)) {
|
||||||
|
tool_join_path(child, path, ff.name, sizeof(child));
|
||||||
|
if (grant_set_subdirs(child, dhandle, object_id, rights))
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int func_grant(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
uint16 rights = 0;
|
||||||
|
char *path = ".";
|
||||||
|
char *objname = NULL;
|
||||||
|
uint16 objtype = GRANT_BINDERY_USER;
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint8 namebuf[48];
|
||||||
|
uint32 object_id;
|
||||||
|
int recurse_subdirs = 0;
|
||||||
|
int i = 1;
|
||||||
|
int have_rights = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc < 2 || tool_is_help_arg(argv[1])) {
|
||||||
|
if (argc < 2)
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(argc < 2 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GRANT rightslist* [FOR path] TO [USER|GROUP] name [options]
|
||||||
|
*/
|
||||||
|
while (i < argc) {
|
||||||
|
if (tool_strsame(argv[i], "FOR") || tool_strsame(argv[i], "TO"))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (tool_is_option(argv[i]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (grant_add_right_word(argv[i], &rights)) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
have_rights = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_rights || i >= argc) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(argv[i], "FOR")) {
|
||||||
|
i++;
|
||||||
|
if (i >= argc) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
path = argv[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc || !tool_strsame(argv[i], "TO")) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i < argc && tool_strsame(argv[i], "USER")) {
|
||||||
|
objtype = GRANT_BINDERY_USER;
|
||||||
|
i++;
|
||||||
|
} else if (i < argc && tool_strsame(argv[i], "GROUP")) {
|
||||||
|
objtype = GRANT_BINDERY_GROUP;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
objname = argv[i++];
|
||||||
|
|
||||||
|
while (i < argc) {
|
||||||
|
if (!tool_is_option(argv[i])) {
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* /FILES is harmless because the explicit path is passed to the
|
||||||
|
* NCP87 trustee-add call. /SUBDIRECTORIES recursively applies the
|
||||||
|
* same grant to all subdirectories below the given path.
|
||||||
|
*/
|
||||||
|
if (tool_strsame(argv[i], "/FILES") || tool_strsame(argv[i], "-FILES") ||
|
||||||
|
tool_strsame(argv[i], "/F") || tool_strsame(argv[i], "-F")) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_strsame(argv[i], "/SUBDIRECTORIES") ||
|
||||||
|
tool_strsame(argv[i], "-SUBDIRECTORIES") ||
|
||||||
|
tool_strsame(argv[i], "/S") || tool_strsame(argv[i], "-S")) {
|
||||||
|
recurse_subdirs = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
grant_usage_error();
|
||||||
|
grant_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool_current_dhandle(&connid, &dhandle)) {
|
||||||
|
fprintf(stdout, "Specified path not locatable.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strmaxcpy(namebuf, objname, sizeof(namebuf) - 1);
|
||||||
|
upstr(namebuf);
|
||||||
|
object_id = ncp_17_35(namebuf, objtype);
|
||||||
|
if (!object_id) {
|
||||||
|
fprintf(stdout, "Object not found.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recurse_subdirs)
|
||||||
|
rc = grant_set_subdirs(path, (uint16)dhandle, object_id, rights);
|
||||||
|
else
|
||||||
|
rc = grant_set_one(path, (uint16)dhandle, object_id, rights);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stdout, "Could not add trustee rights. rc=%d\n", grant_last_rc);
|
||||||
|
return(grant_last_rc ? grant_last_rc : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char header[300];
|
||||||
|
char base[80];
|
||||||
|
char bracket[10];
|
||||||
|
|
||||||
|
tool_header_path(header, path, sizeof(header));
|
||||||
|
tool_basename(base, path, sizeof(base));
|
||||||
|
grant_rights_bracket(rights, bracket);
|
||||||
|
|
||||||
|
fprintf(stdout, "%s\n", header);
|
||||||
|
fprintf(stdout, "%-29.29sRights set to [%s]\n", base, bracket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
30
kern.h
Executable file → Normal file
30
kern.h
Executable file → Normal file
@@ -1,12 +1,28 @@
|
|||||||
/* kern.h Assembler Routinen 20-Nov-93 */
|
/* kern.h Assembler Routinen 20-Nov-93 */
|
||||||
extern int IPXinit(void);
|
#if defined(__WATCOMC__)
|
||||||
extern int IPXopen_socket(UI sock, int live);
|
#define KERN_CALL _Cdecl
|
||||||
extern void IPXclose_socket(UI sock);
|
#else
|
||||||
extern int IPXlisten(ECB *ecb);
|
#define KERN_CALL
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int KERN_CALL IPXinit(void);
|
||||||
|
extern int KERN_CALL IPXopen_socket(UI sock, int live);
|
||||||
|
extern void KERN_CALL IPXclose_socket(UI sock);
|
||||||
|
extern int KERN_CALL IPXlisten(ECB *ecb);
|
||||||
extern void asm_esr_routine(void);
|
extern void asm_esr_routine(void);
|
||||||
extern void esr_routine(ECB *ecb);
|
extern void esr_routine(ECB *ecb);
|
||||||
extern void xmemmove(void *ziel, void *quelle, UI anz);
|
extern void KERN_CALL xmemmove(void *ziel, void *quelle, UI anz);
|
||||||
extern int Net_Call(UI func, void *req, void *repl);
|
extern int KERN_CALL Net_Call(UI func, void *req, void *repl);
|
||||||
|
extern int KERN_CALL C32_MapVar_Probe(UI specLen, UI flag, void *outbuf);
|
||||||
|
extern int KERN_CALL C32_OpenRef_Probe(UI refLo, UI refHi, void *outbuf);
|
||||||
|
extern int KERN_CALL C32_NCP87_Raw5_Probe(UI connLo, UI connHi,
|
||||||
|
void *hdr, UI hdrLen,
|
||||||
|
void *path, UI pathLen,
|
||||||
|
void *rep0, UI rep0Len,
|
||||||
|
void *rep1, UI rep1Len,
|
||||||
|
void *outbuf);
|
||||||
|
#undef KERN_CALL
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
317
kern.lst
317
kern.lst
@@ -1,317 +0,0 @@
|
|||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 1
|
|
||||||
kern.asm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1 ; kern.asm: 20-Nov-93, 21:52
|
|
||||||
2 IDEAL
|
|
||||||
3 P286
|
|
||||||
4 0000 MODEL LARGE
|
|
||||||
5 ; Fuer Turboc gerettet werden muessen folgende Register:
|
|
||||||
6 ; BP, SS, SP, DS, CS u. SI, DI
|
|
||||||
7
|
|
||||||
8 MACRO P_START
|
|
||||||
9 push bp
|
|
||||||
10 mov bp, sp
|
|
||||||
11 ENDM
|
|
||||||
12
|
|
||||||
13 MACRO P_END
|
|
||||||
14 pop bp
|
|
||||||
15 ENDM
|
|
||||||
16
|
|
||||||
17 MACRO PUSH_REGS
|
|
||||||
18 push ds
|
|
||||||
19 push si
|
|
||||||
20 push di
|
|
||||||
21 ENDM
|
|
||||||
22
|
|
||||||
23 MACRO POP_REGS
|
|
||||||
24 pop di
|
|
||||||
25 pop si
|
|
||||||
26 pop ds
|
|
||||||
27 ENDM
|
|
||||||
28
|
|
||||||
29 ;; EXTRN _esr_routine:FAR
|
|
||||||
30
|
|
||||||
31 PUBLIC _IPXinit;
|
|
||||||
32 PUBLIC _IPXopen_socket;
|
|
||||||
33 PUBLIC _IPXclose_socket;
|
|
||||||
34 PUBLIC _IPXlisten;
|
|
||||||
35 ;; PUBLIC _asm_esr_routine;
|
|
||||||
36 PUBLIC _xmemmove;
|
|
||||||
37 PUBLIC _Net_Call;
|
|
||||||
38
|
|
||||||
39 0000 DATASEG
|
|
||||||
40 0000 0000FFFE enterIPX DD FAR
|
|
||||||
41
|
|
||||||
42 0004 CODESEG
|
|
||||||
43 0000 PROC _IPXinit;
|
|
||||||
44 P_START
|
|
||||||
1 45 0000 55 push bp
|
|
||||||
1 46 0001 8B EC mov bp, sp
|
|
||||||
47 PUSH_REGS
|
|
||||||
1 48 0003 1E push ds
|
|
||||||
1 49 0004 56 push si
|
|
||||||
1 50 0005 57 push di
|
|
||||||
51 0006 B8 7A00 mov ax, 7A00h
|
|
||||||
52 0009 CD 2F int 2Fh
|
|
||||||
53 000B 3C FF cmp al, 0FFh
|
|
||||||
54 000D 75 10 jne @@fertig
|
|
||||||
55 000F B9 0000s mov cx, @data
|
|
||||||
56 0012 8E D9 mov ds, cx
|
|
||||||
57 0014 89 3E 0000r mov [WORD PTR enterIPX], di
|
|
||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 2
|
|
||||||
kern.asm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
58 0018 8C C0 mov ax, es
|
|
||||||
59 001A A3 0002r mov [WORD PTR enterIPX+2], ax
|
|
||||||
60 001D B0 01 mov al, 1 ; OK
|
|
||||||
61 001F @@fertig:
|
|
||||||
62 001F B4 00 mov ah, 0
|
|
||||||
63 POP_REGS
|
|
||||||
1 64 0021 5F pop di
|
|
||||||
1 65 0022 5E pop si
|
|
||||||
1 66 0023 1F pop ds
|
|
||||||
67 P_END
|
|
||||||
1 68 0024 5D pop bp
|
|
||||||
69 0025 CB ret ; OK = 1 ; nicht ok = 0
|
|
||||||
70 0026 ENDP
|
|
||||||
71
|
|
||||||
72 0026 PROC _xmemmove;
|
|
||||||
73 ARG z:DATAPTR, q:DATAPTR, nmbr:WORD; Argumente
|
|
||||||
74 0026 FA cli ; Disable Interrupts
|
|
||||||
75 0027 55 push bp
|
|
||||||
76 0028 8B EC mov bp,sp
|
|
||||||
77 002A 8B 4E 0E mov cx, [nmbr];
|
|
||||||
78 002D 0B C9 or cx, cx;
|
|
||||||
79 002F 74 1F jz @@fertig; Anzahl ist 0;
|
|
||||||
80 0031 1E push ds;
|
|
||||||
81 0032 56 push si;
|
|
||||||
82 0033 57 push di;
|
|
||||||
83 0034 9C pushf
|
|
||||||
84 0035 C5 76 0A lds si, [q] ; Quelle
|
|
||||||
85 0038 C4 7E 06 les di, [z] ; Ziel
|
|
||||||
86 003B 3B FE cmp di, si ;
|
|
||||||
87 003D 7C 0A jl @@L1 ; Ziel ist kleiner
|
|
||||||
88 003F FD std ; Richtungsflag setzen
|
|
||||||
89 0040 49 dec cx
|
|
||||||
90 0041 03 F9 add di, cx ; Von oben nach unten kopieren
|
|
||||||
91 0043 03 F1 add si, cx ;
|
|
||||||
92 0045 41 inc cx ; alten Wert wiederherstellen
|
|
||||||
93 0046 EB 02 90 jmp @@L2;
|
|
||||||
94 0049 @@L1:
|
|
||||||
95 0049 FC cld ; Richtungsflag loeschen
|
|
||||||
96 004A @@L2: ; und nun das eigentliche kopieren
|
|
||||||
97 004A F3> A4 REP movsb ;
|
|
||||||
98 004C 9D popf
|
|
||||||
99 004D 5F pop di;
|
|
||||||
100 004E 5E pop si;
|
|
||||||
101 004F 1F pop ds;
|
|
||||||
102 0050 @@fertig:
|
|
||||||
103 0050 5D pop bp;
|
|
||||||
104 0051 FB sti ; enable Interrupts
|
|
||||||
105 0052 CB ret
|
|
||||||
106 0053 ENDP
|
|
||||||
107
|
|
||||||
108 0053 PROC _IPXopen_socket;
|
|
||||||
109 ARG sock:WORD, live:WORD
|
|
||||||
110 P_START
|
|
||||||
1 111 0053 55 push bp
|
|
||||||
1 112 0054 8B EC mov bp, sp
|
|
||||||
113 PUSH_REGS
|
|
||||||
1 114 0056 1E push ds
|
|
||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 3
|
|
||||||
kern.asm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1 115 0057 56 push si
|
|
||||||
1 116 0058 57 push di
|
|
||||||
117 0059 8B 46 08 mov ax, [live]
|
|
||||||
118 005C 8B 56 06 mov dx, [sock]
|
|
||||||
119 005F BB 0000s mov bx, @data
|
|
||||||
120 0062 8E DB mov ds, bx
|
|
||||||
121 0064 BB 0000 mov bx, 0
|
|
||||||
122 0067 FF 1E 0000r call [enterIPX]
|
|
||||||
123 006B 3C FF cmp al, 0FFh
|
|
||||||
124 006D 75 06 jne @@L1
|
|
||||||
125 006F B8 FFFF mov ax, -1 ; Socket already open
|
|
||||||
126 0072 EB 0D 90 jmp @@L3
|
|
||||||
127 0075 @@L1:
|
|
||||||
128 0075 3C FE cmp al, 0FEh
|
|
||||||
129 0077 75 06 jne @@L2
|
|
||||||
130 0079 B8 FFFE mov ax, -2 ; Socket Table full
|
|
||||||
131 007C EB 03 90 jmp @@L3
|
|
||||||
132 007F @@L2:
|
|
||||||
133 007F 8B C2 mov ax, dx
|
|
||||||
134 0081 @@L3:
|
|
||||||
135 POP_REGS
|
|
||||||
1 136 0081 5F pop di
|
|
||||||
1 137 0082 5E pop si
|
|
||||||
1 138 0083 1F pop ds
|
|
||||||
139 P_END
|
|
||||||
1 140 0084 5D pop bp
|
|
||||||
141 0085 CB ret
|
|
||||||
142 0086 ENDP
|
|
||||||
143
|
|
||||||
144 0086 PROC _IPXclose_socket;
|
|
||||||
145 ARG sock:WORD
|
|
||||||
146 P_START
|
|
||||||
1 147 0086 55 push bp
|
|
||||||
1 148 0087 8B EC mov bp, sp
|
|
||||||
149 PUSH_REGS
|
|
||||||
1 150 0089 1E push ds
|
|
||||||
1 151 008A 56 push si
|
|
||||||
1 152 008B 57 push di
|
|
||||||
153 008C 8B 56 06 mov dx, [sock]
|
|
||||||
154 008F BB 0000s mov bx, @data
|
|
||||||
155 0092 8E DB mov ds, bx
|
|
||||||
156 0094 BB 0001 mov bx, 1
|
|
||||||
157 0097 FF 1E 0000r call [enterIPX]
|
|
||||||
158 POP_REGS
|
|
||||||
1 159 009B 5F pop di
|
|
||||||
1 160 009C 5E pop si
|
|
||||||
1 161 009D 1F pop ds
|
|
||||||
162 P_END
|
|
||||||
1 163 009E 5D pop bp
|
|
||||||
164 009F CB ret
|
|
||||||
165 00A0 ENDP
|
|
||||||
166
|
|
||||||
167 00A0 PROC _IPXlisten;
|
|
||||||
168 ARG ecb:DATAPTR
|
|
||||||
169 P_START
|
|
||||||
1 170 00A0 55 push bp
|
|
||||||
1 171 00A1 8B EC mov bp, sp
|
|
||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 4
|
|
||||||
kern.asm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
172 PUSH_REGS
|
|
||||||
1 173 00A3 1E push ds
|
|
||||||
1 174 00A4 56 push si
|
|
||||||
1 175 00A5 57 push di
|
|
||||||
176 00A6 C4 76 06 les si, [ecb] ; Adresse ecb
|
|
||||||
177 00A9 BB 0000s mov bx, @data
|
|
||||||
178 00AC 8E DB mov ds, bx
|
|
||||||
179 00AE BB 0004 mov bx, 4
|
|
||||||
180 00B1 FF 1E 0000r call [enterIPX]
|
|
||||||
181 POP_REGS
|
|
||||||
1 182 00B5 5F pop di
|
|
||||||
1 183 00B6 5E pop si
|
|
||||||
1 184 00B7 1F pop ds
|
|
||||||
185 P_END
|
|
||||||
1 186 00B8 5D pop bp
|
|
||||||
187 00B9 B4 00 mov ah, 0
|
|
||||||
188 00BB CB ret
|
|
||||||
189 00BC ENDP
|
|
||||||
190
|
|
||||||
191 ;; PROC _asm_esr_routine;
|
|
||||||
192 ;; push bp;
|
|
||||||
193 ;; PUSH_REGS;
|
|
||||||
194 ;; mov ax, @data
|
|
||||||
195 ;; mov ds, ax ; F<>r C PROGRAMM
|
|
||||||
196 ;; push es; Adressegment vom EBC
|
|
||||||
197 ;; push si; Adressoffset vom ECB
|
|
||||||
198 ;; call _esr_routine; C ROUTINE
|
|
||||||
199 ;; pop si;
|
|
||||||
200 ;; pop es;
|
|
||||||
201 ;; POP_REGS;
|
|
||||||
202 ;; pop bp;
|
|
||||||
203 ;; cli ; no Interrupt says NOVELL
|
|
||||||
204 ;; ret
|
|
||||||
205 ;; ENDP
|
|
||||||
206
|
|
||||||
207
|
|
||||||
208 00BC PROC _Net_Call;
|
|
||||||
209 ARG func:WORD, req:DATAPTR, repl:DATAPTR; Argumente
|
|
||||||
210 00BC 55 push bp
|
|
||||||
211 00BD 8B EC mov bp, sp
|
|
||||||
212 00BF 8B 46 06 mov ax, [func];
|
|
||||||
213 00C2 1E push ds;
|
|
||||||
214 00C3 56 push si;
|
|
||||||
215 00C4 57 push di;
|
|
||||||
216 00C5 9C pushf
|
|
||||||
217 00C6 C5 76 08 lds si, [req] ; Request
|
|
||||||
218 00C9 C4 7E 0C les di, [repl] ; Reply
|
|
||||||
219 00CC CD 21 int 21h
|
|
||||||
220 00CE 9D popf
|
|
||||||
221 00CF 5F pop di;
|
|
||||||
222 00D0 5E pop si;
|
|
||||||
223 00D1 1F pop ds;
|
|
||||||
224 00D2 5D pop bp;
|
|
||||||
225 00D3 B4 00 mov ah, 0
|
|
||||||
226 00D5 CB ret
|
|
||||||
227 00D6 ENDP
|
|
||||||
228
|
|
||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 5
|
|
||||||
kern.asm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
229 END
|
|
||||||
Turbo Assembler Version 3.1 28/04/96 13:28:50 Page 6
|
|
||||||
Symbol Table
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Symbol Name Type Value
|
|
||||||
|
|
||||||
??DATE Text "28/04/96"
|
|
||||||
??FILENAME Text "kern "
|
|
||||||
??TIME Text "13:28:50"
|
|
||||||
??VERSION Number 030A
|
|
||||||
@32BIT Text 0
|
|
||||||
@@FERTIG Near KERN_TEXT:001F
|
|
||||||
@@FERTIG Near KERN_TEXT:0050
|
|
||||||
@@L1 Near KERN_TEXT:0049
|
|
||||||
@@L1 Near KERN_TEXT:0075
|
|
||||||
@@L2 Near KERN_TEXT:004A
|
|
||||||
@@L2 Near KERN_TEXT:007F
|
|
||||||
@@L3 Near KERN_TEXT:0081
|
|
||||||
@CODE Text KERN_TEXT
|
|
||||||
@CODESIZE Text 1
|
|
||||||
@CPU Text 0787H
|
|
||||||
@CURSEG Text KERN_TEXT
|
|
||||||
@DATA Text DGROUP
|
|
||||||
@DATASIZE Text 1
|
|
||||||
@FILENAME Text KERN
|
|
||||||
@INTERFACE Text 00H
|
|
||||||
@MODEL Text 5
|
|
||||||
@STACK Text DGROUP
|
|
||||||
@WORDSIZE Text 2
|
|
||||||
ECB Number [DGROUP:BP+0006]
|
|
||||||
ENTERIPX Dword DGROUP:0000
|
|
||||||
FUNC Number [DGROUP:BP+0006]
|
|
||||||
LIVE Number [DGROUP:BP+0008]
|
|
||||||
NMBR Number [DGROUP:BP+000E]
|
|
||||||
Q Number [DGROUP:BP+000A]
|
|
||||||
REPL Number [DGROUP:BP+000C]
|
|
||||||
REQ Number [DGROUP:BP+0008]
|
|
||||||
SOCK Number [DGROUP:BP+0006]
|
|
||||||
Z Number [DGROUP:BP+0006]
|
|
||||||
_IPXCLOSE_SOCKET + Far KERN_TEXT:0086
|
|
||||||
(_IPXclose_socket)
|
|
||||||
_IPXINIT (_IPXinit) Far KERN_TEXT:0000
|
|
||||||
_IPXLISTEN (_IPXlisten) Far KERN_TEXT:00A0
|
|
||||||
_IPXOPEN_SOCKET + Far KERN_TEXT:0053
|
|
||||||
(_IPXopen_socket)
|
|
||||||
_NET_CALL (_Net_Call) Far KERN_TEXT:00BC
|
|
||||||
_XMEMMOVE (_xmemmove) Far KERN_TEXT:0026
|
|
||||||
|
|
||||||
Macro Name
|
|
||||||
|
|
||||||
POP_REGS
|
|
||||||
PUSH_REGS
|
|
||||||
P_END
|
|
||||||
P_START
|
|
||||||
|
|
||||||
Groups & Segments Bit Size Align Combine Class
|
|
||||||
|
|
||||||
DGROUP Group
|
|
||||||
_DATA 16 0004 Word Public DATA
|
|
||||||
KERN_TEXT 16 00D6 Word Public CODE
|
|
||||||
|
|
||||||
964
kern_wasm.asm
Normal file
964
kern_wasm.asm
Normal file
@@ -0,0 +1,964 @@
|
|||||||
|
; kern_wasm.asm
|
||||||
|
;
|
||||||
|
; Open Watcom WASM/MASM-syntax port of the old TASM IDEAL kern.asm.
|
||||||
|
; Intended for 16-bit DOS large memory model builds on Linux with Open Watcom v2.
|
||||||
|
;
|
||||||
|
; Keep kern.asm as the historical TASM source and use this file for the
|
||||||
|
; reproducible Open Watcom build.
|
||||||
|
|
||||||
|
.286
|
||||||
|
.model large
|
||||||
|
|
||||||
|
.data
|
||||||
|
enterIPX dd 0
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
public _IPXinit
|
||||||
|
public _IPXopen_socket
|
||||||
|
public _IPXclose_socket
|
||||||
|
public _IPXlisten
|
||||||
|
public _xmemmove
|
||||||
|
public _Net_Call
|
||||||
|
public _C32_NCP87_Raw5_Probe
|
||||||
|
public _C32_OpenRef_Probe
|
||||||
|
public _C32_MapVar_Probe
|
||||||
|
_IPXinit proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
mov ax, 7A00h
|
||||||
|
int 2Fh
|
||||||
|
cmp al, 0FFh
|
||||||
|
jne ipxinit_done
|
||||||
|
|
||||||
|
mov cx, @data
|
||||||
|
mov ds, cx
|
||||||
|
mov word ptr enterIPX, di
|
||||||
|
mov ax, es
|
||||||
|
mov word ptr enterIPX+2, ax
|
||||||
|
mov al, 1
|
||||||
|
|
||||||
|
ipxinit_done:
|
||||||
|
mov ah, 0
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
_IPXinit endp
|
||||||
|
|
||||||
|
_xmemmove proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
; far procedure stack layout, large model:
|
||||||
|
; [bp+0] old bp
|
||||||
|
; [bp+2] return offset
|
||||||
|
; [bp+4] return segment
|
||||||
|
; [bp+6] z offset
|
||||||
|
; [bp+8] z segment
|
||||||
|
; [bp+10] q offset
|
||||||
|
; [bp+12] q segment
|
||||||
|
; [bp+14] nmbr
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov cx, [bp+14]
|
||||||
|
or cx, cx
|
||||||
|
jz xmem_done
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
pushf
|
||||||
|
|
||||||
|
lds si, dword ptr [bp+10]
|
||||||
|
les di, dword ptr [bp+6]
|
||||||
|
cmp di, si
|
||||||
|
jl xmem_forward
|
||||||
|
|
||||||
|
std
|
||||||
|
dec cx
|
||||||
|
add di, cx
|
||||||
|
add si, cx
|
||||||
|
inc cx
|
||||||
|
jmp xmem_copy
|
||||||
|
|
||||||
|
xmem_forward:
|
||||||
|
cld
|
||||||
|
|
||||||
|
xmem_copy:
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
popf
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
xmem_done:
|
||||||
|
pop bp
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
_xmemmove endp
|
||||||
|
|
||||||
|
_IPXopen_socket proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; int IPXopen_socket(UI sock, int live)
|
||||||
|
mov ax, [bp+8] ; live
|
||||||
|
mov dx, [bp+6] ; sock
|
||||||
|
mov bx, @data
|
||||||
|
mov ds, bx
|
||||||
|
mov bx, 0
|
||||||
|
call dword ptr enterIPX
|
||||||
|
|
||||||
|
cmp al, 0FFh
|
||||||
|
jne ipxopen_not_already
|
||||||
|
mov ax, -1 ; socket already open
|
||||||
|
jmp ipxopen_done
|
||||||
|
|
||||||
|
ipxopen_not_already:
|
||||||
|
cmp al, 0FEh
|
||||||
|
jne ipxopen_ok
|
||||||
|
mov ax, -2 ; socket table full
|
||||||
|
jmp ipxopen_done
|
||||||
|
|
||||||
|
ipxopen_ok:
|
||||||
|
mov ax, dx
|
||||||
|
|
||||||
|
ipxopen_done:
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
_IPXopen_socket endp
|
||||||
|
|
||||||
|
_IPXclose_socket proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; void IPXclose_socket(UI sock)
|
||||||
|
mov dx, [bp+6]
|
||||||
|
mov bx, @data
|
||||||
|
mov ds, bx
|
||||||
|
mov bx, 1
|
||||||
|
call dword ptr enterIPX
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
_IPXclose_socket endp
|
||||||
|
|
||||||
|
_IPXlisten proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; int IPXlisten(ECB *ecb)
|
||||||
|
les si, dword ptr [bp+6]
|
||||||
|
mov bx, @data
|
||||||
|
mov ds, bx
|
||||||
|
mov bx, 4
|
||||||
|
call dword ptr enterIPX
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
mov ah, 0
|
||||||
|
ret
|
||||||
|
_IPXlisten endp
|
||||||
|
|
||||||
|
_Net_Call proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
; int Net_Call(UI func, void *req, void *repl)
|
||||||
|
; [bp+6] func
|
||||||
|
; [bp+8] req offset
|
||||||
|
; [bp+10] req segment
|
||||||
|
; [bp+12] repl offset
|
||||||
|
; [bp+14] repl segment
|
||||||
|
mov ax, [bp+6]
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
pushf
|
||||||
|
|
||||||
|
lds si, dword ptr [bp+8]
|
||||||
|
les di, dword ptr [bp+12]
|
||||||
|
int 21h
|
||||||
|
|
||||||
|
popf
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop ds
|
||||||
|
pop bp
|
||||||
|
mov ah, 0
|
||||||
|
ret
|
||||||
|
_Net_Call endp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; int C32_OpenRef_Probe(UI refLo, UI refHi, void *outbuf)
|
||||||
|
;
|
||||||
|
; Opens a Client32 connection by connection reference using the same d32wrap
|
||||||
|
; convention as _CONNOpenByReference / w95ocref.o.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; refLo/refHi = connection reference, e.g. C32PRIMREF returned 0028:0000.
|
||||||
|
;
|
||||||
|
; outbuf:
|
||||||
|
; +00 load AX from D8C1
|
||||||
|
; +02 resolver off
|
||||||
|
; +04 resolver seg
|
||||||
|
; +06 trampoline off
|
||||||
|
; +08 trampoline seg
|
||||||
|
; +0A function off
|
||||||
|
; +0C function seg
|
||||||
|
; +0E return AX
|
||||||
|
; +10 return DX
|
||||||
|
; +12 handle low
|
||||||
|
; +14 handle high
|
||||||
|
_C32_OpenRef_Probe proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 80
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; clear ESI/ECX
|
||||||
|
db 66h, 33h, 0F6h
|
||||||
|
db 66h, 33h, 0C9h
|
||||||
|
|
||||||
|
mov ax, 0D8C1h
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
mov [bp-4], ax ; load AX
|
||||||
|
; resolver ESI -> [bp-8]
|
||||||
|
db 66h, 89h, 76h, 0F8h
|
||||||
|
; trampoline ECX -> [bp-12]
|
||||||
|
db 66h, 89h, 4Eh, 0F4h
|
||||||
|
|
||||||
|
or ax, ax
|
||||||
|
jne c32openref_fail
|
||||||
|
|
||||||
|
; resolve "CONNOpenByReference"
|
||||||
|
push cs
|
||||||
|
push offset c32openref_name
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 8
|
||||||
|
mov [bp-16], ax
|
||||||
|
mov [bp-14], dx
|
||||||
|
or ax, dx
|
||||||
|
jne c32openref_have_func
|
||||||
|
jmp c32openref_fail
|
||||||
|
|
||||||
|
c32openref_have_func:
|
||||||
|
; local output handle dword at [bp-20]
|
||||||
|
mov word ptr [bp-20], 0
|
||||||
|
mov word ptr [bp-18], 0
|
||||||
|
|
||||||
|
; MapLockFlat(&handle, 4) -> flat [bp-24]
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push ss
|
||||||
|
lea ax, -20[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-24], ax
|
||||||
|
mov [bp-22], dx
|
||||||
|
|
||||||
|
; Call NIOS trampoline command 5 / CONNOpenByReference.
|
||||||
|
; This matches d32wrap _CONNOpenByReference after w95ocref:
|
||||||
|
; flat handle ptr,
|
||||||
|
; refHi/refLo,
|
||||||
|
; 0,0,
|
||||||
|
; FEFE FEFE FEFE FEFE,
|
||||||
|
; command 5,
|
||||||
|
; function ptr.
|
||||||
|
push word ptr [bp-22] ; flat handle high
|
||||||
|
push word ptr [bp-24] ; flat handle low
|
||||||
|
push word ptr [bp+8] ; ref high
|
||||||
|
push word ptr [bp+6] ; ref low
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
push 0
|
||||||
|
push 5
|
||||||
|
push word ptr [bp-14] ; function seg
|
||||||
|
push word ptr [bp-16] ; function off
|
||||||
|
call dword ptr [bp-12]
|
||||||
|
add sp, 1cH
|
||||||
|
|
||||||
|
mov [bp-28], ax
|
||||||
|
mov [bp-26], dx
|
||||||
|
|
||||||
|
; UnlockFlat(handle flat, 4)
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push word ptr [bp-22]
|
||||||
|
push word ptr [bp-24]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
jmp short c32openref_store
|
||||||
|
|
||||||
|
c32openref_fail:
|
||||||
|
mov word ptr [bp-16], 0
|
||||||
|
mov word ptr [bp-14], 0
|
||||||
|
mov word ptr [bp-28], 0ffffH
|
||||||
|
mov word ptr [bp-26], 0ffffH
|
||||||
|
mov word ptr [bp-20], 0
|
||||||
|
mov word ptr [bp-18], 0
|
||||||
|
|
||||||
|
c32openref_store:
|
||||||
|
les di, dword ptr [bp+10]
|
||||||
|
|
||||||
|
mov ax, [bp-4]
|
||||||
|
mov es:[di+0], ax
|
||||||
|
mov ax, [bp-8]
|
||||||
|
mov es:[di+2], ax
|
||||||
|
mov ax, [bp-6]
|
||||||
|
mov es:[di+4], ax
|
||||||
|
mov ax, [bp-12]
|
||||||
|
mov es:[di+6], ax
|
||||||
|
mov ax, [bp-10]
|
||||||
|
mov es:[di+8], ax
|
||||||
|
mov ax, [bp-16]
|
||||||
|
mov es:[di+10], ax
|
||||||
|
mov ax, [bp-14]
|
||||||
|
mov es:[di+12], ax
|
||||||
|
mov ax, [bp-28]
|
||||||
|
mov es:[di+14], ax
|
||||||
|
mov ax, [bp-26]
|
||||||
|
mov es:[di+16], ax
|
||||||
|
mov ax, [bp-20]
|
||||||
|
mov es:[di+18], ax
|
||||||
|
mov ax, [bp-18]
|
||||||
|
mov es:[di+20], ax
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
mov sp, bp
|
||||||
|
pop bp
|
||||||
|
xor ah, ah
|
||||||
|
ret
|
||||||
|
|
||||||
|
c32openref_name db 'CONNOpenByReference',0
|
||||||
|
|
||||||
|
_C32_OpenRef_Probe endp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; int C32_MapVar_Probe(UI specLen, UI flag, void *outbuf)
|
||||||
|
;
|
||||||
|
; Exact-ish raw version of w95mconn.o::__C32MapConn16To32 second step.
|
||||||
|
;
|
||||||
|
; It emulates:
|
||||||
|
; C32MAPCONNONE 40 -> server name MARS
|
||||||
|
; NWCSCANCONNINFO(scanIterator/result ptr,
|
||||||
|
; scanInfoLevel=0A, scanConnInfo=NWCString/SPECTDATA "MARS",
|
||||||
|
; scanFlags=1, connInfoVersion=0,
|
||||||
|
; returnInfoLevel=0, returnConnInfo=NULL,
|
||||||
|
; connReference local)
|
||||||
|
;
|
||||||
|
; But calls Client32 CONNScanInfo directly through ECX/NIOS command 0A.
|
||||||
|
;
|
||||||
|
; outbuf:
|
||||||
|
; +00 load AX
|
||||||
|
; +02 resolver off
|
||||||
|
; +04 resolver seg
|
||||||
|
; +06 trampoline off
|
||||||
|
; +08 trampoline seg
|
||||||
|
; +0A function off
|
||||||
|
; +0C function seg
|
||||||
|
; +0E ret AX
|
||||||
|
; +10 ret DX
|
||||||
|
; +12 resultRef low ; corresponds to caller output ptr in w95mconn
|
||||||
|
; +14 resultRef high
|
||||||
|
; +16 connRefLocal low ; corresponds to d32conni local -1c
|
||||||
|
; +18 connRefLocal high
|
||||||
|
_C32_MapVar_Probe proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 140
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; clear ESI/ECX
|
||||||
|
db 66h, 33h, 0F6h
|
||||||
|
db 66h, 33h, 0C9h
|
||||||
|
|
||||||
|
mov ax, 0D8C1h
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
mov [bp-4], ax ; load AX
|
||||||
|
; resolver ESI -> [bp-8]
|
||||||
|
db 66h, 89h, 76h, 0F8h
|
||||||
|
; trampoline ECX -> [bp-12]
|
||||||
|
db 66h, 89h, 4Eh, 0F4h
|
||||||
|
|
||||||
|
or ax, ax
|
||||||
|
jne c32mapvar_fail
|
||||||
|
|
||||||
|
; resolve "CONNScanInfo"
|
||||||
|
push cs
|
||||||
|
push offset c32mapvar_name
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 8
|
||||||
|
mov [bp-16], ax
|
||||||
|
mov [bp-14], dx
|
||||||
|
or ax, dx
|
||||||
|
jne c32mapvar_have_func
|
||||||
|
jmp c32mapvar_fail
|
||||||
|
|
||||||
|
c32mapvar_have_func:
|
||||||
|
; resultRef/output dword at [bp-20], init 0
|
||||||
|
mov word ptr [bp-20], 0
|
||||||
|
mov word ptr [bp-18], 0
|
||||||
|
|
||||||
|
; connReference local dword at [bp-24], init 0
|
||||||
|
mov word ptr [bp-24], 0
|
||||||
|
mov word ptr [bp-22], 0
|
||||||
|
|
||||||
|
; string buffer at [bp-80], copy "MARS", zero padded enough
|
||||||
|
lea di, -80[bp]
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
mov byte ptr es:[di+0], 'M'
|
||||||
|
mov byte ptr es:[di+1], 'A'
|
||||||
|
mov byte ptr es:[di+2], 'R'
|
||||||
|
mov byte ptr es:[di+3], 'S'
|
||||||
|
mov byte ptr es:[di+4], 0
|
||||||
|
|
||||||
|
; Map string buffer len 31h -> [bp-28]
|
||||||
|
push 0
|
||||||
|
push 31H
|
||||||
|
push ss
|
||||||
|
lea ax, -80[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-28], ax
|
||||||
|
mov [bp-26], dx
|
||||||
|
|
||||||
|
; Build SPECTDATA/NWCString transfer block at [bp-48], len 10h.
|
||||||
|
; Mirrors d32conni initialization for server-name scan.
|
||||||
|
mov ax, [bp+6]
|
||||||
|
mov word ptr [bp-48], ax
|
||||||
|
mov word ptr [bp-46], 0
|
||||||
|
mov ax, [bp-28]
|
||||||
|
mov word ptr [bp-44], ax
|
||||||
|
mov ax, [bp-26]
|
||||||
|
mov word ptr [bp-42], ax
|
||||||
|
mov word ptr [bp-40], 1
|
||||||
|
mov word ptr [bp-38], 0
|
||||||
|
mov word ptr [bp-36], 0
|
||||||
|
mov word ptr [bp-34], 0
|
||||||
|
|
||||||
|
; Map scanInfo spectdata block len 10h -> [bp-32]
|
||||||
|
push 0
|
||||||
|
push 10H
|
||||||
|
push ss
|
||||||
|
lea ax, -48[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-32], ax
|
||||||
|
mov [bp-30], dx
|
||||||
|
|
||||||
|
; Map resultRef/output len4 -> [bp-56] (this is w95mconn caller ptr)
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push ss
|
||||||
|
lea ax, -20[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-56], ax
|
||||||
|
mov [bp-54], dx
|
||||||
|
|
||||||
|
; Map connReference local len4 -> [bp-60]
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push ss
|
||||||
|
lea ax, -24[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-60], ax
|
||||||
|
mov [bp-58], dx
|
||||||
|
|
||||||
|
; Raw CONNScanInfo via NIOS, following d32wrap _CONNScanInfo
|
||||||
|
; argument order from d32conni L$115.
|
||||||
|
push word ptr [bp-58] ; connReference flat high
|
||||||
|
push word ptr [bp-60] ; connReference flat low
|
||||||
|
|
||||||
|
push 0 ; returnConnInfo flat high = NULL
|
||||||
|
push 0 ; returnConnInfo flat low = NULL
|
||||||
|
|
||||||
|
push 0 ; returnInfoLen high
|
||||||
|
push 0 ; returnInfoLen low
|
||||||
|
|
||||||
|
push 0 ; returnInfoLevel high
|
||||||
|
push 4 ; returnInfoLevel low, as d32conni L$115
|
||||||
|
|
||||||
|
push 0 ; scan flag high
|
||||||
|
push word ptr [bp+8] ; scan flag low
|
||||||
|
|
||||||
|
push word ptr [bp-30] ; scanInfo flat high
|
||||||
|
push word ptr [bp-32] ; scanInfo flat low
|
||||||
|
|
||||||
|
push 0 ; scanInfoLevel high
|
||||||
|
push 0aH ; scanInfoLevel low = SERVER_NAME
|
||||||
|
|
||||||
|
push word ptr [bp-54] ; scanIterator/result flat high
|
||||||
|
push word ptr [bp-56] ; scanIterator/result flat low
|
||||||
|
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
push 0fefeH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 0aH
|
||||||
|
push word ptr [bp-14]
|
||||||
|
push word ptr [bp-16]
|
||||||
|
call dword ptr [bp-12]
|
||||||
|
add sp, 30H
|
||||||
|
|
||||||
|
mov [bp-64], ax
|
||||||
|
mov [bp-62], dx
|
||||||
|
|
||||||
|
; Unlock maps.
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push word ptr [bp-58]
|
||||||
|
push word ptr [bp-60]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push word ptr [bp-54]
|
||||||
|
push word ptr [bp-56]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 10H
|
||||||
|
push word ptr [bp-30]
|
||||||
|
push word ptr [bp-32]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 31H
|
||||||
|
push word ptr [bp-26]
|
||||||
|
push word ptr [bp-28]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-8]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
jmp short c32mapvar_store
|
||||||
|
|
||||||
|
c32mapvar_fail:
|
||||||
|
mov word ptr [bp-16], 0
|
||||||
|
mov word ptr [bp-14], 0
|
||||||
|
mov word ptr [bp-64], 0ffffH
|
||||||
|
mov word ptr [bp-62], 0ffffH
|
||||||
|
mov word ptr [bp-20], 0
|
||||||
|
mov word ptr [bp-18], 0
|
||||||
|
mov word ptr [bp-24], 0
|
||||||
|
mov word ptr [bp-22], 0
|
||||||
|
|
||||||
|
c32mapvar_store:
|
||||||
|
les di, dword ptr [bp+10]
|
||||||
|
|
||||||
|
mov ax, [bp-4]
|
||||||
|
mov es:[di+0], ax
|
||||||
|
mov ax, [bp-8]
|
||||||
|
mov es:[di+2], ax
|
||||||
|
mov ax, [bp-6]
|
||||||
|
mov es:[di+4], ax
|
||||||
|
mov ax, [bp-12]
|
||||||
|
mov es:[di+6], ax
|
||||||
|
mov ax, [bp-10]
|
||||||
|
mov es:[di+8], ax
|
||||||
|
mov ax, [bp-16]
|
||||||
|
mov es:[di+10], ax
|
||||||
|
mov ax, [bp-14]
|
||||||
|
mov es:[di+12], ax
|
||||||
|
mov ax, [bp-64]
|
||||||
|
mov es:[di+14], ax
|
||||||
|
mov ax, [bp-62]
|
||||||
|
mov es:[di+16], ax
|
||||||
|
mov ax, [bp-20]
|
||||||
|
mov es:[di+18], ax
|
||||||
|
mov ax, [bp-18]
|
||||||
|
mov es:[di+20], ax
|
||||||
|
mov ax, [bp-24]
|
||||||
|
mov es:[di+22], ax
|
||||||
|
mov ax, [bp-22]
|
||||||
|
mov es:[di+24], ax
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
mov sp, bp
|
||||||
|
pop bp
|
||||||
|
xor ah, ah
|
||||||
|
ret
|
||||||
|
|
||||||
|
c32mapvar_name db 'CONNScanInfo',0
|
||||||
|
|
||||||
|
_C32_MapVar_Probe endp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; int C32_NCP87_Raw5_Probe(UI connLo, UI connHi,
|
||||||
|
; void *hdr, UI hdrLen,
|
||||||
|
; void *path, UI pathLen,
|
||||||
|
; void *rep0, UI rep0Len,
|
||||||
|
; void *rep1, UI rep1Len,
|
||||||
|
; void *outbuf)
|
||||||
|
;
|
||||||
|
; Same as C32_NCP87_Raw_Probe but uses d32wrap-compatible 5-slot
|
||||||
|
; fragment tables: 5 * 8 = 0x28 bytes for request and reply.
|
||||||
|
_C32_NCP87_Raw5_Probe proc far
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 180
|
||||||
|
|
||||||
|
push ds
|
||||||
|
push es
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
|
||||||
|
; clear ESI/ECX
|
||||||
|
db 66h, 33h, 0F6h
|
||||||
|
db 66h, 33h, 0C9h
|
||||||
|
|
||||||
|
mov ax, 0D8C1h
|
||||||
|
int 2Fh
|
||||||
|
|
||||||
|
mov [bp-2], ax
|
||||||
|
db 66h, 89h, 76h, 0FAh ; resolver at [bp-6]
|
||||||
|
db 66h, 89h, 4Eh, 0F6h ; trampoline at [bp-10]
|
||||||
|
|
||||||
|
or ax, ax
|
||||||
|
jne raw5_fail
|
||||||
|
|
||||||
|
; resolve COMPATNcpRequestReply
|
||||||
|
push cs
|
||||||
|
push offset raw5_name
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 8
|
||||||
|
mov [bp-14], ax
|
||||||
|
mov [bp-12], dx
|
||||||
|
or ax, dx
|
||||||
|
jne raw5_have_func
|
||||||
|
jmp raw5_fail
|
||||||
|
|
||||||
|
raw5_have_func:
|
||||||
|
; actual reply len dword at [bp-36]
|
||||||
|
mov word ptr [bp-36], 0
|
||||||
|
mov word ptr [bp-34], 0
|
||||||
|
|
||||||
|
; map hdr -> [bp-20]
|
||||||
|
push 0
|
||||||
|
push word ptr [bp+0eH]
|
||||||
|
push word ptr [bp+0cH]
|
||||||
|
push word ptr [bp+0aH]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-20], ax
|
||||||
|
mov [bp-18], dx
|
||||||
|
|
||||||
|
; map path -> [bp-24]
|
||||||
|
push 0
|
||||||
|
push word ptr [bp+14H]
|
||||||
|
push word ptr [bp+12H]
|
||||||
|
push word ptr [bp+10H]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-24], ax
|
||||||
|
mov [bp-22], dx
|
||||||
|
|
||||||
|
; map rep0 -> [bp-28]
|
||||||
|
push 0
|
||||||
|
push word ptr [bp+1aH]
|
||||||
|
push word ptr [bp+18H]
|
||||||
|
push word ptr [bp+16H]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-28], ax
|
||||||
|
mov [bp-26], dx
|
||||||
|
|
||||||
|
; map rep1 -> [bp-32]
|
||||||
|
push 0
|
||||||
|
push word ptr [bp+20H]
|
||||||
|
push word ptr [bp+1eH]
|
||||||
|
push word ptr [bp+1cH]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-32], ax
|
||||||
|
mov [bp-30], dx
|
||||||
|
|
||||||
|
; zero req table [bp-160] len 40 and reply table [bp-120] len 40
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
cld
|
||||||
|
xor ax, ax
|
||||||
|
lea di, -160[bp]
|
||||||
|
mov cx, 20
|
||||||
|
rep stosw
|
||||||
|
lea di, -120[bp]
|
||||||
|
mov cx, 20
|
||||||
|
rep stosw
|
||||||
|
|
||||||
|
; req entry0 = hdr
|
||||||
|
mov ax, [bp-20]
|
||||||
|
mov [bp-160], ax
|
||||||
|
mov ax, [bp-18]
|
||||||
|
mov [bp-158], ax
|
||||||
|
mov ax, [bp+0eH]
|
||||||
|
mov [bp-156], ax
|
||||||
|
mov word ptr [bp-154], 0
|
||||||
|
|
||||||
|
; req entry1 = path
|
||||||
|
mov ax, [bp-24]
|
||||||
|
mov [bp-152], ax
|
||||||
|
mov ax, [bp-22]
|
||||||
|
mov [bp-150], ax
|
||||||
|
mov ax, [bp+14H]
|
||||||
|
mov [bp-148], ax
|
||||||
|
mov word ptr [bp-146], 0
|
||||||
|
|
||||||
|
; reply entry0 = rep0
|
||||||
|
mov ax, [bp-28]
|
||||||
|
mov [bp-120], ax
|
||||||
|
mov ax, [bp-26]
|
||||||
|
mov [bp-118], ax
|
||||||
|
mov ax, [bp+1aH]
|
||||||
|
mov [bp-116], ax
|
||||||
|
mov word ptr [bp-114], 0
|
||||||
|
|
||||||
|
; reply entry1 = rep1
|
||||||
|
mov ax, [bp-32]
|
||||||
|
mov [bp-112], ax
|
||||||
|
mov ax, [bp-30]
|
||||||
|
mov [bp-110], ax
|
||||||
|
mov ax, [bp+20H]
|
||||||
|
mov [bp-108], ax
|
||||||
|
mov word ptr [bp-106], 0
|
||||||
|
|
||||||
|
; map req table 0x28 -> [bp-40]
|
||||||
|
push 0
|
||||||
|
push 28H
|
||||||
|
push ss
|
||||||
|
lea ax, -160[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-40], ax
|
||||||
|
mov [bp-38], dx
|
||||||
|
|
||||||
|
; map reply table 0x28 -> [bp-44]
|
||||||
|
push 0
|
||||||
|
push 28H
|
||||||
|
push ss
|
||||||
|
lea ax, -120[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-44], ax
|
||||||
|
mov [bp-42], dx
|
||||||
|
|
||||||
|
; map actual reply len -> [bp-48]
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push ss
|
||||||
|
lea ax, -36[bp]
|
||||||
|
push ax
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
mov [bp-48], ax
|
||||||
|
mov [bp-46], dx
|
||||||
|
|
||||||
|
; call COMPAT via NIOS command 8
|
||||||
|
push word ptr [bp-46]
|
||||||
|
push word ptr [bp-48]
|
||||||
|
push word ptr [bp-42]
|
||||||
|
push word ptr [bp-44]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
push word ptr [bp-38]
|
||||||
|
push word ptr [bp-40]
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
push 0
|
||||||
|
push 57H
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
|
push word ptr [bp+8]
|
||||||
|
push word ptr [bp+6]
|
||||||
|
push 0
|
||||||
|
push 8
|
||||||
|
push word ptr [bp-12]
|
||||||
|
push word ptr [bp-14]
|
||||||
|
call dword ptr [bp-10]
|
||||||
|
add sp, 28H
|
||||||
|
|
||||||
|
mov [bp-52], ax
|
||||||
|
mov [bp-50], dx
|
||||||
|
|
||||||
|
; unlock important mappings only; ignore return
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
push word ptr [bp-46]
|
||||||
|
push word ptr [bp-48]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 28H
|
||||||
|
push word ptr [bp-42]
|
||||||
|
push word ptr [bp-44]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
push 0
|
||||||
|
push 28H
|
||||||
|
push word ptr [bp-38]
|
||||||
|
push word ptr [bp-40]
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
call dword ptr [bp-6]
|
||||||
|
add sp, 0cH
|
||||||
|
|
||||||
|
jmp short raw5_store
|
||||||
|
|
||||||
|
raw5_fail:
|
||||||
|
mov word ptr [bp-14], 0
|
||||||
|
mov word ptr [bp-12], 0
|
||||||
|
mov word ptr [bp-52], 0ffffH
|
||||||
|
mov word ptr [bp-50], 0ffffH
|
||||||
|
mov word ptr [bp-36], 0
|
||||||
|
mov word ptr [bp-34], 0
|
||||||
|
|
||||||
|
raw5_store:
|
||||||
|
les di, dword ptr [bp+22H]
|
||||||
|
mov ax, [bp-2]
|
||||||
|
mov es:[di+0], ax
|
||||||
|
mov ax, [bp-6]
|
||||||
|
mov es:[di+2], ax
|
||||||
|
mov ax, [bp-4]
|
||||||
|
mov es:[di+4], ax
|
||||||
|
mov ax, [bp-10]
|
||||||
|
mov es:[di+6], ax
|
||||||
|
mov ax, [bp-8]
|
||||||
|
mov es:[di+8], ax
|
||||||
|
mov ax, [bp-14]
|
||||||
|
mov es:[di+10], ax
|
||||||
|
mov ax, [bp-12]
|
||||||
|
mov es:[di+12], ax
|
||||||
|
mov ax, [bp-52]
|
||||||
|
mov es:[di+14], ax
|
||||||
|
mov ax, [bp-50]
|
||||||
|
mov es:[di+16], ax
|
||||||
|
mov ax, [bp-36]
|
||||||
|
mov es:[di+18], ax
|
||||||
|
mov ax, [bp-34]
|
||||||
|
mov es:[di+20], ax
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop es
|
||||||
|
pop ds
|
||||||
|
mov sp, bp
|
||||||
|
pop bp
|
||||||
|
xor ah, ah
|
||||||
|
ret
|
||||||
|
|
||||||
|
raw5_name db 'COMPATNcpRequestReply',0
|
||||||
|
|
||||||
|
_C32_NCP87_Raw5_Probe endp
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
465
map.c
Executable file → Normal file
465
map.c
Executable file → Normal file
@@ -24,23 +24,24 @@ static void show_map(uint8 *drvstr)
|
|||||||
if ((!get_drive_info(j, &connid, &dhandle, &flags)) && flags){
|
if ((!get_drive_info(j, &connid, &dhandle, &flags)) && flags){
|
||||||
char servern[52];
|
char servern[52];
|
||||||
char path[256];
|
char path[256];
|
||||||
|
servern[0]='\0';
|
||||||
if (flags & 0x80) { /* lokal DRIVE */
|
if (flags & 0x80) { /* lokal DRIVE */
|
||||||
path[0]= '\\';
|
path[0]= '\\';
|
||||||
if (j < 2){
|
if (j < 2){
|
||||||
strcpy(path, "DISK LW");
|
strcpy(path, "maps to a local disk.");
|
||||||
} else if (getcurdir(j+1, path+1)) {
|
} else if (getcurdir(j+1, path+1)) {
|
||||||
strcpy(path, "LW !OK");
|
strcpy(path, "maps to a local disk.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (get_dir_path(dhandle, path)) {
|
if (get_dir_path(dhandle, path)) {
|
||||||
strcpy(path, "DHANDLE !OK");
|
strcpy(path, "DHANDLE !OK");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (connid) {
|
if (connid) {
|
||||||
get_fs_name(connid, servern);
|
get_fs_name(connid, servern);
|
||||||
strcat(servern, "\\");
|
strcat(servern, "\\");
|
||||||
} else servern[0]='\0';
|
} else servern[0]='\0';
|
||||||
printf("MAP %c: = %s%s\n", (char)j+'A', servern, path);
|
}
|
||||||
|
if (flags & 0x80) printf("Drive %c: %s\n", (char)j+'A', path); else printf("Drive %c: = %s%s\n", (char)j+'A', servern, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,9 +58,9 @@ static void do_map(int drive, NWPATH *nwp)
|
|||||||
if (flags & 0x80) { /* lokal DRIVE */
|
if (flags & 0x80) { /* lokal DRIVE */
|
||||||
path[0]= '\\';
|
path[0]= '\\';
|
||||||
if (drive < 2){
|
if (drive < 2){
|
||||||
strcpy(path, "DISK LW");
|
strcpy(path, "maps to a local disk.");
|
||||||
} else if (getcurdir(drive+1, path+1)) {
|
} else if (getcurdir(drive+1, path+1)) {
|
||||||
strcpy(path, "LW !OK");
|
strcpy(path, "maps to a local disk.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (get_dir_path(dhandle, path)) {
|
if (get_dir_path(dhandle, path)) {
|
||||||
@@ -76,22 +77,49 @@ static void do_map(int drive, NWPATH *nwp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int do_map(int drive, NWPATH *nwp)
|
static int do_map(int drive, NWPATH *nwp, int delete)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
if (drive > -1 && drive < 32) {
|
if (drive > -1 && drive < 32) {
|
||||||
uint8 nmdrive[3];
|
uint8 connid = 0;
|
||||||
nmdrive[0] = drive+'A';
|
uint8 dhandle = 0;
|
||||||
nmdrive[1] = ':';
|
uint8 flags = 0;
|
||||||
nmdrive[2] = '\0';
|
|
||||||
result = redir_device_drive(0x4, nmdrive, nwp->path);
|
if (delete) {
|
||||||
|
if (!get_drive_info(drive, &connid, &dhandle, &flags)
|
||||||
|
&& flags && !(flags & 0x80) && connid) {
|
||||||
|
result = dealloc_dir_handle(dhandle);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The old mars-dosutils MAP used DOS redirector INT 21h AX=5F03h.
|
||||||
|
* NetWare Client32 returns AX=0001 for that call, while Novell MAP
|
||||||
|
* works. Use the NetWare shell/NCP "Allocate Permanent Directory
|
||||||
|
* Handle" path instead; this is what the surrounding code already
|
||||||
|
* provides via alloc_permanent_dir_handle().
|
||||||
|
*/
|
||||||
|
if (!get_drive_info(drive, &connid, &dhandle, &flags)
|
||||||
|
&& flags && !(flags & 0x80) && connid) {
|
||||||
|
(void)dealloc_dir_handle(dhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = alloc_permanent_dir_handle(0, nwp->path, drive + 'A', NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some requesters historically accepted lowercase drive letters in
|
||||||
|
* this call. Keep this only as compatibility fallback.
|
||||||
|
*/
|
||||||
|
if (result < 0)
|
||||||
|
result = alloc_permanent_dir_handle(0, nwp->path, drive + 'a', NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int parse_argv(uint8 *drvstr, NWPATH *nwpath,
|
static int parse_argv(uint8 *drvstr, NWPATH *nwpath,
|
||||||
int argc, char *argv[], int smode)
|
int argc, char *argv[], int smode, int argvmode)
|
||||||
{
|
{
|
||||||
int k = 0;
|
int k = 0;
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
@@ -149,6 +177,7 @@ static int parse_argv(uint8 *drvstr, NWPATH *nwpath,
|
|||||||
} /* while *p */
|
} /* while *p */
|
||||||
} /* while k */
|
} /* while k */
|
||||||
if (mode == 30) {
|
if (mode == 30) {
|
||||||
|
if (argvmode != 1)
|
||||||
getcwd((char *)nwpath->buff, sizeof(nwpath->buff));
|
getcwd((char *)nwpath->buff, sizeof(nwpath->buff));
|
||||||
mode = 40;
|
mode = 40;
|
||||||
}
|
}
|
||||||
@@ -159,21 +188,142 @@ static int parse_argv(uint8 *drvstr, NWPATH *nwpath,
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int func_map(int argc, char *argv[])
|
|
||||||
|
static int parse_pathins_arg(uint8 *drvstr, NWPATH *nwp,
|
||||||
|
int argc, char *argv[], int mode);
|
||||||
|
static int set_search_native(uint8 *drvstr, NWPATH *nwp, int pathmode);
|
||||||
|
static int show_search(uint8 *drvstr);
|
||||||
|
|
||||||
|
static int map_same_arg(char *a, char *b)
|
||||||
|
{
|
||||||
|
while (*a || *b) {
|
||||||
|
int ca = *a++;
|
||||||
|
int cb = *b++;
|
||||||
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
||||||
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
||||||
|
if (ca != cb) return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int map_is_drive_arg(char *s)
|
||||||
|
{
|
||||||
|
if (!s || !s[0] || s[1] != ':' || s[2]) return(0);
|
||||||
|
if (s[0] >= 'A' && s[0] <= 'Z') return(1);
|
||||||
|
if (s[0] >= 'a' && s[0] <= 'z') return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int map_drive_index(char *s)
|
||||||
|
{
|
||||||
|
if (s[0] >= 'a' && s[0] <= 'z') return(s[0] - 'a');
|
||||||
|
return(s[0] - 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void map_drive_name(char *dst, char *src)
|
||||||
|
{
|
||||||
|
dst[0] = src[0];
|
||||||
|
if (dst[0] >= 'a' && dst[0] <= 'z') dst[0] -= 32;
|
||||||
|
dst[1] = ':';
|
||||||
|
dst[2] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int map_handle_path_command(int argc, char *argv[], int pathmode)
|
||||||
{
|
{
|
||||||
uint8 drvstr[22];
|
uint8 drvstr[22];
|
||||||
NWPATH nwpath;
|
NWPATH nwpath;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_pathins_arg(drvstr, &nwpath, argc, argv, pathmode);
|
||||||
|
if (!rc) {
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (*(nwpath.path) || pathmode == 1)
|
||||||
|
result = set_search_native(drvstr, &nwpath, pathmode);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
|
else if (pathmode != 1)
|
||||||
|
show_search(drvstr);
|
||||||
|
else
|
||||||
|
fprintf(stdout, "The search mapping for drive S%d: was deleted\n",
|
||||||
|
(int)drvstr[1]);
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int func_map(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
uint8 drvstr[22];
|
||||||
|
NWPATH nwpath;
|
||||||
|
|
||||||
if (!ipx_init()) argc = 1;
|
if (!ipx_init()) argc = 1;
|
||||||
if (!parse_argv(drvstr, &nwpath, argc, argv, 0)) {
|
|
||||||
if (*(nwpath.path)) {
|
/*
|
||||||
if (do_map(*drvstr - 'A', &nwpath)< 0)
|
* Novell MAP accepts subcommands through MAP itself:
|
||||||
|
* MAP DEL H:
|
||||||
|
* MAP INS S1:=SYS:PUBLIC
|
||||||
|
* MAP DEL S1:
|
||||||
|
* The original mars-dosutils exposed those mainly as MAPDEL/PATHINS/PATHDEL,
|
||||||
|
* so handle the Novell syntax here and then reuse the existing primitives.
|
||||||
|
*/
|
||||||
|
if (argc > 1) {
|
||||||
|
if (map_same_arg(argv[1], "/?") || map_same_arg(argv[1], "-?") ||
|
||||||
|
map_same_arg(argv[1], "?")) {
|
||||||
|
fprintf(stderr, "Directory \"/?\" is not locatable.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_same_arg(argv[1], "INS") || map_same_arg(argv[1], "INSERT")) {
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(map_handle_path_command(argc - 1, argv + 1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_same_arg(argv[1], "DEL") || map_same_arg(argv[1], "DELETE")) {
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_is_drive_arg(argv[2])) {
|
||||||
|
char dname[3];
|
||||||
|
int drive = map_drive_index(argv[2]);
|
||||||
|
|
||||||
|
if (do_map(drive, &nwpath, 1) < 0) {
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
map_drive_name(dname, argv[2]);
|
||||||
|
fprintf(stdout, "The mapping for drive %s has been deleted.\n", dname);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(map_handle_path_command(argc - 1, argv + 1, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_argv(drvstr, &nwpath, argc, argv, 0, mode)) {
|
||||||
|
if (*(nwpath.path) || mode==1) {
|
||||||
|
if (do_map(*drvstr - 'A', &nwpath, mode)< 0)
|
||||||
fprintf(stderr, "MAP Error\n");
|
fprintf(stderr, "MAP Error\n");
|
||||||
}
|
}
|
||||||
|
if (mode != 1)
|
||||||
show_map(drvstr);
|
show_map(drvstr);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------- */
|
/* ------------------------------------------------- */
|
||||||
static int show_search(uint8 *drvstr)
|
static int show_search(uint8 *drvstr)
|
||||||
{
|
{
|
||||||
@@ -183,38 +333,42 @@ static int show_search(uint8 *drvstr)
|
|||||||
get_search_drive_vektor(drives);
|
get_search_drive_vektor(drives);
|
||||||
while (p->drivenummer != 0xff && j++ < 16) {
|
while (p->drivenummer != 0xff && j++ < 16) {
|
||||||
char path[256];
|
char path[256];
|
||||||
char nwname[256];
|
char nwname_path[300];
|
||||||
|
|
||||||
|
|
||||||
if ( !*drvstr || j == *(drvstr+1)) {
|
if ( !*drvstr || j == *(drvstr+1)) {
|
||||||
if (p->flags && !(p->flags & 0x80)){
|
|
||||||
get_fs_name(p->u.fs.connid, nwname);
|
|
||||||
if (get_dir_path(p->u.fs.dhandle, path)) {
|
|
||||||
strcpy(path, "ERROR NW");
|
|
||||||
}
|
|
||||||
(void)xadd_char(nwname, '\\', 20);
|
|
||||||
} else {
|
|
||||||
nwname[0] = '\0';
|
|
||||||
/*
|
|
||||||
nwname[0] = '<';
|
|
||||||
strcpy(nwname+1, "LOCAL");
|
|
||||||
*/
|
|
||||||
if (p->drivenummer == 0xfe){
|
if (p->drivenummer == 0xfe){
|
||||||
strcpy(path, p->u.d.dospath);
|
strcpy(path, p->dospath);
|
||||||
} else if (getcurdir((int)(p->drivenummer)+1, path)) {
|
} else {
|
||||||
strcpy(path, "ERROR DOS");
|
*path = p->drivenummer+'A';
|
||||||
|
*(path+1) = ':';
|
||||||
|
strcpy(path+2, p->dospath);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
(void)xadd_char(nwname, '>', 20);
|
if (p->flags && !(p->flags & 0x80)){
|
||||||
*/
|
char *pp=nwname_path;
|
||||||
|
*pp++ = '[';
|
||||||
|
get_fs_name(p->connid, pp);
|
||||||
|
pp +=strlen(pp);
|
||||||
|
*pp++='\\';
|
||||||
|
if (get_dir_path(p->dhandle, pp)) {
|
||||||
|
strcpy(pp, "ERROR NW");
|
||||||
}
|
}
|
||||||
strcat(nwname, path);
|
pp += strlen(pp);
|
||||||
printf("SEARCH%2d = %c: %s\n", j, (char)(p->drivenummer)+'A', nwname);
|
*pp ++= ']';
|
||||||
|
*pp = '\0';
|
||||||
|
} else {
|
||||||
|
*nwname_path = '\0';
|
||||||
|
}
|
||||||
|
printf("SEARCH%2d = %s %s\n", j, path, nwname_path);
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_search(uint8 *drvstr, NWPATH *nwp)
|
static int set_search(uint8 *drvstr, NWPATH *nwp, int pathmode)
|
||||||
{
|
{
|
||||||
int result=-1;
|
int result=-1;
|
||||||
SEARCH_VECTOR drives;
|
SEARCH_VECTOR drives;
|
||||||
@@ -222,31 +376,252 @@ static int set_search(uint8 *drvstr, NWPATH *nwp)
|
|||||||
int j=0;
|
int j=0;
|
||||||
int entry = (*drvstr=='s') ? *(drvstr+1) : 0;
|
int entry = (*drvstr=='s') ? *(drvstr+1) : 0;
|
||||||
get_search_drive_vektor(drives);
|
get_search_drive_vektor(drives);
|
||||||
|
|
||||||
while (p->drivenummer != 0xff && j++ < 16) {
|
while (p->drivenummer != 0xff && j++ < 16) {
|
||||||
if (!entry && (p->drivenummer + 'A' == *drvstr)) entry=j;
|
if (!entry && (p->drivenummer + 'A' == *drvstr)) entry=j;
|
||||||
|
if (p->drivenummer + 'A' == nwp->path[0] && nwp->path[1] == ':'
|
||||||
|
&& !strcmp(nwp->path+2, p->dospath)) {
|
||||||
|
p->drivenummer=0xfe;
|
||||||
|
*(p->dospath) = '\0';
|
||||||
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry > 0) {
|
if (entry > 0) {
|
||||||
if (entry > 16) entry = 16;
|
if (entry > 16) entry = 16;
|
||||||
if (--entry < j) p = drives+entry;
|
if (pathmode == 2 && entry <= j && entry < 16) { /* insert modus */
|
||||||
|
int k=j+1-entry;
|
||||||
|
if (j < 16) {
|
||||||
|
p++;
|
||||||
|
k++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
while (k--) {
|
||||||
|
memcpy(p, p-1, sizeof(SEARCH_VECTOR_ENTRY));
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (--entry < j)
|
||||||
|
p = drives+entry;
|
||||||
else (p+1)->drivenummer = 0xff;
|
else (p+1)->drivenummer = 0xff;
|
||||||
|
p->flags = 0;
|
||||||
p->drivenummer = 0xfe;
|
p->drivenummer = 0xfe;
|
||||||
strcpy(p->u.d.dospath, nwp->path);
|
if (pathmode==1)
|
||||||
|
*(p->dospath) = '\0';
|
||||||
|
else
|
||||||
|
strcpy(p->dospath, nwp->path);
|
||||||
result = set_search_drive_vektor(drives);
|
result = set_search_drive_vektor(drives);
|
||||||
}
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int func_path(int argc, char *argv[])
|
|
||||||
|
static int path_is_drive_path(uint8 *path)
|
||||||
|
{
|
||||||
|
if (!path || !path[0] || path[1] != ':') return(0);
|
||||||
|
if (path[0] >= 'A' && path[0] <= 'Z') return(1);
|
||||||
|
if (path[0] >= 'a' && path[0] <= 'z') return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void upstr_local(uint8 *s)
|
||||||
|
{
|
||||||
|
while (*s) {
|
||||||
|
if (*s >= 'a' && *s <= 'z') *s -= 0x20;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_pathins_arg(uint8 *drvstr, NWPATH *nwp, int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
char joined[512];
|
||||||
|
char *p;
|
||||||
|
char *q;
|
||||||
|
int slot = 0;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
*drvstr = '\0';
|
||||||
|
memset(nwp, 0, sizeof(NWPATH));
|
||||||
|
nwp->path = nwp->buff;
|
||||||
|
*(nwp->buff) = '\0';
|
||||||
|
|
||||||
|
if (argc < 2) return(1);
|
||||||
|
|
||||||
|
joined[0] = '\0';
|
||||||
|
for (k = 1; k < argc; k++) {
|
||||||
|
if (k > 1) strcat(joined, " ");
|
||||||
|
strncat(joined, argv[k], sizeof(joined) - strlen(joined) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = joined;
|
||||||
|
while (*p == ' ' || *p == '\t') p++;
|
||||||
|
|
||||||
|
if (*p != 'S' && *p != 's') return(-1);
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while (*p >= '0' && *p <= '9') {
|
||||||
|
slot = slot * 10 + (*p - '0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot < 1 || slot > 16) return(-1);
|
||||||
|
if (*p != ':') return(-1);
|
||||||
|
p++;
|
||||||
|
|
||||||
|
drvstr[0] = 's';
|
||||||
|
drvstr[1] = (uint8)slot;
|
||||||
|
drvstr[2] = '\0';
|
||||||
|
|
||||||
|
while (*p == ' ' || *p == '\t') p++;
|
||||||
|
|
||||||
|
if (mode == 1) {
|
||||||
|
/* PATHDEL S1: */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '=') p++;
|
||||||
|
while (*p == ' ' || *p == '\t') p++;
|
||||||
|
|
||||||
|
if (!*p) return(-1);
|
||||||
|
|
||||||
|
q = nwp->buff;
|
||||||
|
while (*p && (q - nwp->buff) < (int)sizeof(nwp->buff) - 1) {
|
||||||
|
*q++ = *p++;
|
||||||
|
}
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
upstr_local(nwp->buff);
|
||||||
|
nwp->path = nwp->buff;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_search_native(uint8 *drvstr, NWPATH *nwp, int pathmode)
|
||||||
|
{
|
||||||
|
int result=-1;
|
||||||
|
SEARCH_VECTOR drives;
|
||||||
|
SEARCH_VECTOR_ENTRY *p=drives;
|
||||||
|
int j=0;
|
||||||
|
int entry = (*drvstr=='s') ? *(drvstr+1) : 0;
|
||||||
|
|
||||||
|
get_search_drive_vektor(drives);
|
||||||
|
|
||||||
|
while (p->drivenummer != 0xff && j++ < 16) {
|
||||||
|
if (!entry && path_is_drive_path(nwp->path)
|
||||||
|
&& (p->drivenummer + 'A' == nwp->path[0])) entry=j;
|
||||||
|
|
||||||
|
if (path_is_drive_path(nwp->path)
|
||||||
|
&& p->drivenummer + 'A' == nwp->path[0]
|
||||||
|
&& !strcmp(nwp->path+2, p->dospath)) {
|
||||||
|
p->drivenummer=0xfe;
|
||||||
|
*(p->dospath) = '\0';
|
||||||
|
p->flags = 0;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry > 0) {
|
||||||
|
if (entry > 16) entry = 16;
|
||||||
|
|
||||||
|
if (pathmode == 2 && entry <= j && entry < 16) { /* insert modus */
|
||||||
|
int k=j+1-entry;
|
||||||
|
if (j < 16) {
|
||||||
|
p++;
|
||||||
|
k++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
while (k--) {
|
||||||
|
memcpy(p, p-1, sizeof(SEARCH_VECTOR_ENTRY));
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--entry < j)
|
||||||
|
p = drives+entry;
|
||||||
|
else
|
||||||
|
(p+1)->drivenummer = 0xff;
|
||||||
|
|
||||||
|
memset(p, 0, sizeof(SEARCH_VECTOR_ENTRY));
|
||||||
|
|
||||||
|
if (pathmode==1) {
|
||||||
|
p->drivenummer = 0xfe;
|
||||||
|
*(p->dospath) = '\0';
|
||||||
|
result = set_search_drive_vektor(drives);
|
||||||
|
} else if (path_is_drive_path(nwp->path)) {
|
||||||
|
p->flags = 0;
|
||||||
|
p->drivenummer = (uint8)(nwp->path[0] - 'A');
|
||||||
|
if (nwp->path[0] >= 'a' && nwp->path[0] <= 'z')
|
||||||
|
p->drivenummer = (uint8)(nwp->path[0] - 'a');
|
||||||
|
strmaxcpy(p->dospath, nwp->path+2, sizeof(p->dospath)-1);
|
||||||
|
result = set_search_drive_vektor(drives);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Search path entries are not drive mappings. The original code stores
|
||||||
|
* the NetWare path text directly in dospath with drivenummer=0xfe.
|
||||||
|
* Client32 keeps/prints these entries correctly; allocating a permanent
|
||||||
|
* directory handle here made set_search_drive_vektor() return success,
|
||||||
|
* but the entry did not actually replace SEARCH1.
|
||||||
|
*/
|
||||||
|
p->flags = 0;
|
||||||
|
p->drivenummer = 0xfe;
|
||||||
|
strmaxcpy(p->dospath, nwp->path, sizeof(p->dospath)-1);
|
||||||
|
result = set_search_drive_vektor(drives);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int func_path(int argc, char *argv[], int mode)
|
||||||
{
|
{
|
||||||
uint8 drvstr[22];
|
uint8 drvstr[22];
|
||||||
NWPATH nwpath;
|
NWPATH nwpath;
|
||||||
if (!parse_argv(drvstr, &nwpath, argc, argv, 1)) {
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PATH/PATHINS/PATHDEL need their own parser. The old parse_argv()
|
||||||
|
* rejects common login-script syntax such as:
|
||||||
|
* PATHINS S1:=SYS:PUBLIC
|
||||||
|
* MAP INS S1:=SYS:PUBLIC
|
||||||
|
*/
|
||||||
|
if (argc < 2) {
|
||||||
|
show_search("");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = parse_pathins_arg(drvstr, &nwpath, argc, argv, mode);
|
||||||
|
if (!rc) {
|
||||||
int result=0;
|
int result=0;
|
||||||
if (*(nwpath.path)) result=set_search(drvstr, &nwpath);
|
if (*(nwpath.path) || mode==1)
|
||||||
|
result=set_search_native(drvstr, &nwpath, mode);
|
||||||
|
if (mode != 1)
|
||||||
show_search(drvstr);
|
show_search(drvstr);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Cannot interpret line. errcode=-1\n");
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remove_nwpathes(void)
|
||||||
|
{
|
||||||
|
SEARCH_VECTOR drives;
|
||||||
|
SEARCH_VECTOR_ENTRY *p=drives;
|
||||||
|
int j=0;
|
||||||
|
get_search_drive_vektor(drives);
|
||||||
|
while (p->drivenummer != 0xff && j++ < 16) {
|
||||||
|
if (p->flags && !(p->flags & 0x80)){
|
||||||
|
p->flags=0;
|
||||||
|
p->drivenummer=0xfe;
|
||||||
|
*(p->dospath) ='\0';
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
set_search_drive_vektor(drives);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
103
ncpcall.c
Executable file → Normal file
103
ncpcall.c
Executable file → Normal file
@@ -283,3 +283,106 @@ int ncp_17_4b(uint8 *cryptkey, uint8 *objname, uint16 objtyp,
|
|||||||
if (neterrno) return(-1);
|
if (neterrno) return(-1);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ncp_17_37(uint32 last_id, uint16 objtyp, uint8 *pattern,
|
||||||
|
BINDERY_OBJECT *target)
|
||||||
|
/* scan bindery object */
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 func;
|
||||||
|
uint8 last_id[4];
|
||||||
|
uint8 typ[2];
|
||||||
|
uint8 patlen;
|
||||||
|
uint8 pattern[48];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 object_id[4];
|
||||||
|
uint8 object_type[2];
|
||||||
|
uint8 object_name[48];
|
||||||
|
uint8 object_flags;
|
||||||
|
uint8 object_security;
|
||||||
|
uint8 object_has_prop;
|
||||||
|
} repl;
|
||||||
|
int patlen = (pattern) ? min(48, strlen(pattern)) : 1;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
req.func = 0x37;
|
||||||
|
U32_TO_BE32(last_id, req.last_id);
|
||||||
|
U16_TO_BE16(objtyp, req.typ);
|
||||||
|
req.patlen = (uint8)patlen;
|
||||||
|
if (pattern) memcpy(req.pattern, pattern, patlen);
|
||||||
|
else req.pattern[0] = '*';
|
||||||
|
req.len = 8 + patlen;
|
||||||
|
|
||||||
|
repl.len = sizeof(repl) - sizeof(uint16);
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xE300, &req, &repl);
|
||||||
|
if (neterrno) return(-1);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
target->object_id = GET_BE32(repl.object_id);
|
||||||
|
target->object_type = GET_BE16(repl.object_type);
|
||||||
|
memcpy(target->object_name, repl.object_name, 48);
|
||||||
|
target->object_name[48] = '\0';
|
||||||
|
deb(target->object_name);
|
||||||
|
target->object_flags = repl.object_flags;
|
||||||
|
target->object_security = repl.object_security;
|
||||||
|
target->object_has_prop = repl.object_has_prop;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ncp_17_3d(uint16 objtyp, uint8 *objname, int segment,
|
||||||
|
uint8 *propname, NW_PROPERTY *target)
|
||||||
|
/* read bindery property value */
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 func;
|
||||||
|
uint8 typ[2];
|
||||||
|
uint8 buff[1+48+1+1+16];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 value[128];
|
||||||
|
uint8 more_flag;
|
||||||
|
uint8 property_flag;
|
||||||
|
} repl;
|
||||||
|
uint8 *p = req.buff;
|
||||||
|
int objlen = min(48, strlen(objname));
|
||||||
|
int proplen = min(16, strlen(propname));
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
req.func = 0x3d;
|
||||||
|
U16_TO_BE16(objtyp, req.typ);
|
||||||
|
|
||||||
|
*p++ = (uint8)objlen;
|
||||||
|
memcpy(p, objname, objlen);
|
||||||
|
p += objlen;
|
||||||
|
|
||||||
|
*p++ = (uint8)segment;
|
||||||
|
|
||||||
|
*p++ = (uint8)proplen;
|
||||||
|
memcpy(p, propname, proplen);
|
||||||
|
|
||||||
|
req.len = 6 + objlen + proplen;
|
||||||
|
repl.len = sizeof(repl) - sizeof(uint16);
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xE300, &req, &repl);
|
||||||
|
if (neterrno) return(-1);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
memcpy(target->value, repl.value, 128);
|
||||||
|
target->more_flag = repl.more_flag;
|
||||||
|
target->property_flag = repl.property_flag;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
123
net.c
Executable file → Normal file
123
net.c
Executable file → Normal file
@@ -1,65 +1,118 @@
|
|||||||
/* net.c 14-Mar-96 */
|
/* net.c */
|
||||||
/* simple client programm to act with mars_nwe */
|
#define VERS_DATE "21-May-96"
|
||||||
|
/* simple client program to act with mars_nwe */
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
char *funcname=NULL;
|
char *funcname=NULL;
|
||||||
typedef int (*NET_FUNC)(int argc, char *argv[]);
|
char prgpath[65];
|
||||||
|
|
||||||
|
typedef int (*NET_FUNC)(int argc, char *argv[], int mode);
|
||||||
|
|
||||||
static struct s_net_functions {
|
static struct s_net_functions {
|
||||||
char *name;
|
char *name;
|
||||||
char *description;
|
char *description;
|
||||||
NET_FUNC func;
|
NET_FUNC func;
|
||||||
|
int mode;
|
||||||
} net_functions[] = {
|
} net_functions[] = {
|
||||||
{"LOGIN", "login to Server as User" , func_login },
|
|
||||||
{"MAP", "list maps and map drives" , func_map },
|
{"SPAWN", "spawn program(command file)" , func_exec , 0},
|
||||||
{"PATH", "list and set search path" , func_path },
|
{"EXEC", "execute program(command file)", func_exec , 1},
|
||||||
{"LOGOUT", "logout from Server", func_logout },
|
{"ECHO", "echoes string (command file)" , func_echo , 0},
|
||||||
#if 0
|
{"CD", "change directory (command file)" , func_cwd , 0},
|
||||||
{"SLIST", "list Servers", func_slist },
|
{"LOGIN", "login to server as user" , func_login , 0},
|
||||||
#endif
|
{"PROFILE","read command file" , func_profile, 0},
|
||||||
{"PASSWD", "change password", func_passwd },
|
{"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},
|
||||||
|
{"RIGHTS", "display effective file/directory rights",func_rights, 0},
|
||||||
|
{"SLIST", "list servers", func_slist , 0},
|
||||||
|
{"PASSWD", "change password", func_passwd , 0},
|
||||||
#if 1
|
#if 1
|
||||||
{"TESTS", "only testroutines!", func_tests },
|
{"TESTS", "only testroutines!", func_tests , 0},
|
||||||
#endif
|
#endif
|
||||||
{"DEBUG", "set debug level, for mars_nwe only !", func_debug }
|
{"DEBUG", "set debug level, for mars_nwe only !", func_debug , 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_FUNCS (sizeof(net_functions) / sizeof(struct s_net_functions))
|
#define MAX_FUNCS (sizeof(net_functions) / sizeof(struct s_net_functions))
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_path(char *path)
|
||||||
|
{
|
||||||
|
char buf[100];
|
||||||
|
strmaxcpy(buf, path, sizeof(buf)-1);
|
||||||
|
korrpath(buf);
|
||||||
|
get_path_fn(buf, prgpath, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
NET_FUNC func = NULL;
|
int result = -0xff;
|
||||||
int result = -1;
|
get_path(argv[0]);
|
||||||
if (argc > 1) {
|
result = call_func_entry(argc, argv);
|
||||||
char funcn[200];
|
if (result == -0xff)
|
||||||
int k= MAX_FUNCS;
|
result = call_func_entry(argc-1, argv+1);
|
||||||
strmaxcpy(funcn, argv[1], sizeof(funcn)-1);
|
if (result == -0xff) {
|
||||||
upstr(funcn);
|
|
||||||
while (k--) {
|
|
||||||
if (!strcmp(funcn, net_functions[k].name)) {
|
|
||||||
func=net_functions[k].func;
|
|
||||||
funcname=net_functions[k].name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (func != NULL) {
|
|
||||||
if (ipx_init() || func == func_map) {
|
|
||||||
result = (*func) (argc-1, &(argv[1]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int k= MAX_FUNCS;
|
int k= MAX_FUNCS;
|
||||||
char progname[256];
|
char progname[256];
|
||||||
strmaxcpy(progname, argv[0], sizeof(progname)-1);
|
strmaxcpy(progname, argv[0], sizeof(progname)-1);
|
||||||
upstr(progname);
|
upstr(progname);
|
||||||
fprintf(stderr, "\n"
|
fprintf(stderr, "\n"
|
||||||
"****************************************************************\n"
|
|
||||||
"* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *\n"
|
"* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *\n"
|
||||||
"****************************************************************\n\n" );
|
" Version: %s\n\n", VERS_DATE);
|
||||||
|
|
||||||
fprintf(stderr, "Usage:\t%s func ... \nfuncs:", progname);
|
fprintf(stderr, "Usage:\t%s func ... \nfuncs:", progname);
|
||||||
while (k--) {
|
while (k--) {
|
||||||
if (net_functions[k].func) {
|
if (net_functions[k].func) {
|
||||||
|
|||||||
125
net.h
Executable file → Normal file
125
net.h
Executable file → Normal file
@@ -1,4 +1,4 @@
|
|||||||
/* net.h: 01-Feb-96 */
|
/* net.h: 20-May-96 */
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
||||||
@@ -15,8 +15,13 @@
|
|||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#include <direct.h>
|
||||||
|
extern int tool_page_line(int *line_count, int *continuous);
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef unsigned int UI;
|
typedef unsigned int UI;
|
||||||
|
typedef unsigned int uint;
|
||||||
typedef unsigned char UC;
|
typedef unsigned char UC;
|
||||||
typedef unsigned char uint8;
|
typedef unsigned char uint8;
|
||||||
typedef unsigned short int uint16;
|
typedef unsigned short int uint16;
|
||||||
@@ -54,7 +59,7 @@ typedef struct {
|
|||||||
uint16 fragment_count; /* Anzahl Fragment Buffers */
|
uint16 fragment_count; /* Anzahl Fragment Buffers */
|
||||||
uint8 *fragment_1;
|
uint8 *fragment_1;
|
||||||
uint16 fragment_1_size;
|
uint16 fragment_1_size;
|
||||||
/* K”nnen auch mehr sein */
|
/* K�nnen auch mehr sein */
|
||||||
} ECB;
|
} ECB;
|
||||||
|
|
||||||
#include "kern.h"
|
#include "kern.h"
|
||||||
@@ -102,39 +107,93 @@ typedef struct {
|
|||||||
#define NWCLIENT 4
|
#define NWCLIENT 4
|
||||||
#define NWBIND 5
|
#define NWBIND 5
|
||||||
|
|
||||||
|
#define NCP_BINDERY_FSERVER 0x0004
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 object_id;
|
||||||
|
uint16 object_type;
|
||||||
|
uint8 object_name[49];
|
||||||
|
uint8 object_flags;
|
||||||
|
uint8 object_security;
|
||||||
|
uint8 object_has_prop;
|
||||||
|
} BINDERY_OBJECT;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8 value[128];
|
||||||
|
uint8 more_flag;
|
||||||
|
uint8 property_flag;
|
||||||
|
} NW_PROPERTY;
|
||||||
|
|
||||||
|
|
||||||
/* net.c */
|
/* net.c */
|
||||||
extern char *funcname;
|
extern char *funcname;
|
||||||
|
extern char prgpath[];
|
||||||
|
|
||||||
|
extern int call_func_entry(int argc, char *argv[]);
|
||||||
|
|
||||||
/* tools.c */
|
/* tools.c */
|
||||||
extern void clear_kb(void);
|
extern void clear_kb(void);
|
||||||
extern int key_pressed(void);
|
extern int key_pressed(void);
|
||||||
extern int ask_user(char *p, ...);
|
extern int ask_user(char *p, ...);
|
||||||
|
#define xfree(p) x_x_xfree((char **)&(p))
|
||||||
|
extern void x_x_xfree(char **p);
|
||||||
|
extern char *xmalloc(uint size);
|
||||||
|
extern char *xcmalloc(uint size);
|
||||||
|
|
||||||
extern int strmaxcpy(char *dest, char *source, int len);
|
extern int strmaxcpy(char *dest, char *source, int len);
|
||||||
extern char *xadd_char(char *s, int c, int maxlen);
|
extern char *xadd_char(char *s, int c, int maxlen);
|
||||||
extern uint8 *upstr(uint8 *s);
|
extern uint8 *upstr(uint8 *s);
|
||||||
|
extern void korrpath(char *s);
|
||||||
|
extern void get_path_fn(char *s, char *p, char *fn);
|
||||||
|
|
||||||
|
/* Shared DOS utility helpers. Keep command frontends small so the
|
||||||
|
* historical multicall net.exe can later be split into smaller groups. */
|
||||||
|
extern int tool_strsame(char *a, char *b);
|
||||||
|
extern int tool_is_help_arg(char *s);
|
||||||
|
extern int tool_is_option(char *s);
|
||||||
|
extern int tool_is_files_option(char *s);
|
||||||
|
extern int tool_is_subdirs_option(char *s);
|
||||||
|
extern int tool_get_current_drive(void);
|
||||||
|
extern int tool_current_dhandle(uint8 *connid, uint8 *dhandle);
|
||||||
|
extern int tool_current_prefix(char *out, int max);
|
||||||
|
extern int tool_is_current_path(char *path);
|
||||||
|
extern void tool_upcopy(char *dst, char *src, int max);
|
||||||
|
extern void tool_basename(char *dst, char *src, int max);
|
||||||
|
extern void tool_header_path(char *out, char *path, int max);
|
||||||
|
extern int tool_is_dot_dir(char *name);
|
||||||
|
extern void tool_join_path(char *out, char *base, char *name, int max);
|
||||||
|
extern int tool_has_wildcards(char *path);
|
||||||
|
extern void tool_parent_pattern(char *dir, char *pattern, char *path,
|
||||||
|
int maxdir, int maxpat);
|
||||||
|
|
||||||
|
#define reb(s) deb((s)),leb((s))
|
||||||
|
|
||||||
|
extern void deb(uint8 *s);
|
||||||
|
extern void leb(uint8 *s);
|
||||||
|
|
||||||
|
|
||||||
#define add_char(s, c) xadd_char((s), (c), -1)
|
#define add_char(s, c) xadd_char((s), (c), -1)
|
||||||
|
|
||||||
extern char *getglobenv(char *option);
|
extern char *getglobenv(char *option);
|
||||||
extern int putglobenv(char *option);
|
extern int putglobenv(char *option);
|
||||||
|
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
/* Borland C compatibility wrappers implemented in tools.c. */
|
||||||
|
extern int getcurdir(int drive, char *directory);
|
||||||
|
extern void setdisk(int drive);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NETCALLS */
|
/* NETCALLS */
|
||||||
#define DRIVE_ADD 1
|
#define DRIVE_ADD 1
|
||||||
#define DRIVE_INSERT 2
|
#define DRIVE_INSERT 2
|
||||||
#define DRIVE_DELETE 3
|
#define DRIVE_DELETE 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8 drivenummer; /* 0xff, 0xfe f<EFBFBD>r DOSPATH mit Pfad */
|
uint8 drivenummer; /* 0xff=last of list, 0xfe only DOSPATH */
|
||||||
uint8 flags;
|
uint8 flags; /* 0x80 = local drive */
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
char dospath[65];
|
char dospath[65];
|
||||||
} d;
|
|
||||||
struct fs {
|
|
||||||
uint8 connid;
|
uint8 connid;
|
||||||
uint8 dhandle;
|
uint8 dhandle;
|
||||||
} fs;
|
|
||||||
} u;
|
|
||||||
} SEARCH_VECTOR_ENTRY;
|
} SEARCH_VECTOR_ENTRY;
|
||||||
|
|
||||||
typedef SEARCH_VECTOR_ENTRY SEARCH_VECTOR[17];
|
typedef SEARCH_VECTOR_ENTRY SEARCH_VECTOR[17];
|
||||||
@@ -148,6 +207,12 @@ extern int neterrno;
|
|||||||
alloc_dir_handle(0x13, (dhandle), (path), (drive), (rights))
|
alloc_dir_handle(0x13, (dhandle), (path), (drive), (rights))
|
||||||
|
|
||||||
extern int ipx_init(void);
|
extern int ipx_init(void);
|
||||||
|
extern int logout(void);
|
||||||
|
extern int redir_device_drive(int devicetyp, uint8 *devname, uint8 *remotename);
|
||||||
|
extern int list_redir(int index, int *devicetyp, uint8 *devname, uint8 *remotename);
|
||||||
|
extern int get_drive_info(uint8 drivenumber, uint8 *connid,
|
||||||
|
uint8 *dhandle, uint8 *statusflags);
|
||||||
|
extern int get_fs_name(int connid, char *name);
|
||||||
|
|
||||||
extern int alloc_dir_handle(int func, int dhandle, char *path,
|
extern int alloc_dir_handle(int func, int dhandle, char *path,
|
||||||
int driveletter, uint8 *effrights);
|
int driveletter, uint8 *effrights);
|
||||||
@@ -168,11 +233,13 @@ extern int ncp_16_02(int dirhandle,
|
|||||||
uint32 *creattime,
|
uint32 *creattime,
|
||||||
uint32 *owner_id);
|
uint32 *owner_id);
|
||||||
|
|
||||||
|
extern int ncp_14_46(uint32 *obj_id);
|
||||||
extern int ncp_17_02(int module, int debuglevel);
|
extern int ncp_17_02(int module, int debuglevel);
|
||||||
extern int ncp_17_14(uint8 *objname, uint16 objtyp, uint8 *password);
|
extern int ncp_17_14(uint8 *objname, uint16 objtyp, uint8 *password);
|
||||||
extern int ncp_17_17(uint8 *key);
|
extern int ncp_17_17(uint8 *key);
|
||||||
extern int ncp_17_18(uint8 *cryptkey, uint8 *objname, uint16 objtyp);
|
extern int ncp_17_18(uint8 *cryptkey, uint8 *objname, uint16 objtyp);
|
||||||
extern uint32 ncp_17_35(uint8 *objname, uint16 objtyp);
|
extern uint32 ncp_17_35(uint8 *objname, uint16 objtyp);
|
||||||
|
extern int ncp_17_36(uint32 obj_id, uint8 *objname, uint16 *objtyp);
|
||||||
extern int ncp_17_40(uint8 *objname, uint16 objtyp, uint8 *password,
|
extern int ncp_17_40(uint8 *objname, uint16 objtyp, uint8 *password,
|
||||||
uint8 *newpassword);
|
uint8 *newpassword);
|
||||||
|
|
||||||
@@ -180,23 +247,43 @@ extern int ncp_17_4b(uint8 *cryptkey, uint8 *objname, uint16 objtyp,
|
|||||||
int passwx, uint8 *newpassword);
|
int passwx, uint8 *newpassword);
|
||||||
|
|
||||||
/* map.c */
|
/* map.c */
|
||||||
extern int func_map(int argc, char *argv[]);
|
extern int func_map (int argc, char *argv[], int mode);
|
||||||
extern int func_path(int argc, char *argv[]);
|
extern int func_path (int argc, char *argv[], int mode);
|
||||||
|
extern void remove_nwpathes(void);
|
||||||
|
|
||||||
/* login.c */
|
/* login.c */
|
||||||
extern int func_login(int argc, char *argv[]);
|
extern int func_login (int argc, char *argv[], int mode);
|
||||||
extern int func_logout(int argc, char *argv[]);
|
extern int func_logout (int argc, char *argv[], int mode);
|
||||||
extern int func_passwd(int argc, char *argv[]);
|
extern int func_passwd (int argc, char *argv[], int mode);
|
||||||
|
extern int func_profile(int argc, char *argv[], int mode);
|
||||||
|
extern int func_cwd (int argc, char *argv[], int mode);
|
||||||
|
extern int func_echo (int argc, char *argv[], int mode);
|
||||||
|
extern int func_exec (int argc, char *argv[], int mode);
|
||||||
|
extern int read_command_file(char *fstr);
|
||||||
|
|
||||||
/* slist.c */
|
/* slist.c */
|
||||||
extern int func_slist(int argc, char *argv[]);
|
extern int func_slist (int argc, char *argv[], int mode);
|
||||||
|
|
||||||
/* nwdebug.c */
|
/* nwdebug.c */
|
||||||
extern int func_debug(int argc, char *argv[]);
|
extern int func_debug (int argc, char *argv[], int mode);
|
||||||
|
|
||||||
/* nwtests.c */
|
/* nwtests.c */
|
||||||
extern int func_tests(int argc, char *argv[]);
|
extern int func_tests (int argc, char *argv[], int mode);
|
||||||
|
|
||||||
|
/* capture.c */
|
||||||
|
extern int func_capture(int argc, char *argv[], int mode);
|
||||||
|
|
||||||
|
/* flag.c */
|
||||||
|
extern int func_flag (int argc, char *argv[], int mode);
|
||||||
|
extern int func_flagdir(int argc, char *argv[], int mode);
|
||||||
|
extern int func_grant (int argc, char *argv[], int mode);
|
||||||
|
extern int func_revoke(int argc, char *argv[], int mode);
|
||||||
|
extern int func_remove(int argc, char *argv[], int mode);
|
||||||
|
extern int func_rights (int argc, char *argv[], int mode);
|
||||||
|
|
||||||
|
|
||||||
|
extern int ncp_17_37(uint32 last_id, uint16 objtyp, uint8 *pattern,
|
||||||
|
BINDERY_OBJECT *target);
|
||||||
|
extern int ncp_17_3d(uint16 objtyp, uint8 *objname, int segment,
|
||||||
|
uint8 *propname, NW_PROPERTY *target);
|
||||||
|
|
||||||
|
|||||||
29
netcall.c
Executable file → Normal file
29
netcall.c
Executable file → Normal file
@@ -49,6 +49,8 @@ int logout(void)
|
|||||||
|
|
||||||
int redir_device_drive(int devicetyp, uint8 *devname, uint8 *remotename)
|
int redir_device_drive(int devicetyp, uint8 *devname, uint8 *remotename)
|
||||||
/* if devicetyp == -1, the redir is canceled */
|
/* if devicetyp == -1, the redir is canceled */
|
||||||
|
/* devicetyp 3 = printer */
|
||||||
|
/* devicetyp 4 = disk drive */
|
||||||
{
|
{
|
||||||
REGS regs;
|
REGS regs;
|
||||||
SREGS sregs;
|
SREGS sregs;
|
||||||
@@ -157,16 +159,15 @@ int get_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec)
|
|||||||
char *p1 = path;
|
char *p1 = path;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (*path && *path++ !=';') len++;
|
while (*path && *path++ !=';') len++;
|
||||||
if (*(p1+1) == ':'
|
if (*(p1+1) == ':' && *p1 >= 'A' && *p1 <= 'Z') {
|
||||||
&& *p1 >= 'A' && *p1 <= 'Z' &&
|
|
||||||
(len==2 || (len == 3 && *(p1+2) == '.'))) {
|
|
||||||
v->drivenummer = *p1 - 'A';
|
v->drivenummer = *p1 - 'A';
|
||||||
get_drive_info(v->drivenummer, &(v->u.fs.connid),
|
get_drive_info(v->drivenummer, &(v->connid),
|
||||||
&(v->u.fs.dhandle), &(v->flags));
|
&(v->dhandle), &(v->flags));
|
||||||
|
strmaxcpy(v->dospath, p1+2, min(len-2, sizeof(v->dospath)-1));
|
||||||
} else {
|
} else {
|
||||||
v->flags = 0;
|
v->flags = 0;
|
||||||
v->drivenummer = 0xfe; /* ergibt ? */
|
v->drivenummer = 0xfe; /* ergibt ? */
|
||||||
strmaxcpy(v->u.d.dospath, p1, len);
|
strmaxcpy(v->dospath, p1, min(len, sizeof(v->dospath)-1));
|
||||||
}
|
}
|
||||||
(++v)->drivenummer = 0xff;
|
(++v)->drivenummer = 0xff;
|
||||||
if (*path == ';') path++;
|
if (*path == ';') path++;
|
||||||
@@ -181,20 +182,29 @@ int set_search_drive_vektor(SEARCH_VECTOR_ENTRY *vec)
|
|||||||
char *p=path;
|
char *p=path;
|
||||||
SEARCH_VECTOR_ENTRY *v;
|
SEARCH_VECTOR_ENTRY *v;
|
||||||
int plen=strlen(path_env_name);
|
int plen=strlen(path_env_name);
|
||||||
|
int maxcount=16;
|
||||||
strcpy(path, path_env_name);
|
strcpy(path, path_env_name);
|
||||||
path[plen] = '=';
|
path[plen] = '=';
|
||||||
path[++plen] = '\0';
|
path[++plen] = '\0';
|
||||||
while ((NULL != (v = vec++)) && v->drivenummer != 0xff){
|
|
||||||
|
while (maxcount-- && (NULL != (v = vec++)) && v->drivenummer != 0xff){
|
||||||
|
if (v->drivenummer < 26 || *(v->dospath)) {
|
||||||
if (p > path) *p++=';';
|
if (p > path) *p++=';';
|
||||||
else p+=plen;
|
else p+=plen;
|
||||||
if (v->drivenummer < 26) {
|
if (v->drivenummer < 26) {
|
||||||
*p++ = (char) v->drivenummer + 'A';
|
*p++ = (char) v->drivenummer + 'A';
|
||||||
*p++ = ':';
|
*p++ = ':';
|
||||||
|
if (*v->dospath) {
|
||||||
|
strcpy(p, v->dospath);
|
||||||
|
p+= strlen(v->dospath);
|
||||||
|
} else {
|
||||||
*p++='.';
|
*p++='.';
|
||||||
*p ='\0';
|
*p ='\0';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
strcpy(p, v->u.d.dospath);
|
strcpy(p, v->dospath);
|
||||||
p+= strlen(v->u.d.dospath);
|
p+= strlen(v->dospath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(putglobenv(path));
|
return(putglobenv(path));
|
||||||
@@ -231,7 +241,6 @@ int alloc_dir_handle(int func,
|
|||||||
printf("alloc_dir_handle, path=%s, len=%d, disk=%c\n", path, pathlen, driveletter);
|
printf("alloc_dir_handle, path=%s, len=%d, disk=%c\n", path, pathlen, driveletter);
|
||||||
*/
|
*/
|
||||||
neterrno = Net_Call(0xE200, &req, &repl);
|
neterrno = Net_Call(0xE200, &req, &repl);
|
||||||
fprintf(stderr, "neterrno=%d\n", neterrno);
|
|
||||||
if (neterrno && neterrno != 0xff) return(-1);
|
if (neterrno && neterrno != 0xff) return(-1);
|
||||||
|
|
||||||
if (effrights) *effrights = repl.effrights;
|
if (effrights) *effrights = repl.effrights;
|
||||||
|
|||||||
BIN
netold.exe
Executable file
BIN
netold.exe
Executable file
Binary file not shown.
113
nwcrypt.c
Executable file → Normal file
113
nwcrypt.c
Executable file → Normal file
@@ -118,6 +118,7 @@ static buf32 encryptkeys =
|
|||||||
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
||||||
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "nwcrypt.h"
|
#include "nwcrypt.h"
|
||||||
static void
|
static void
|
||||||
shuffle1(buf32 temp, unsigned char *target)
|
shuffle1(buf32 temp, unsigned char *target)
|
||||||
@@ -210,4 +211,116 @@ nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
|
|||||||
til[s] = k[s] ^ k[15 - s];
|
til[s] = k[s] ^ k[15 - s];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
newshuffle[256] =
|
||||||
|
{
|
||||||
|
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
|
||||||
|
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
|
||||||
|
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
|
||||||
|
0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
|
||||||
|
|
||||||
|
0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
|
||||||
|
0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
|
||||||
|
0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
|
||||||
|
0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
|
||||||
|
|
||||||
|
0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
|
||||||
|
0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
|
||||||
|
0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
|
||||||
|
0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
|
||||||
|
|
||||||
|
0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
|
||||||
|
0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
|
||||||
|
0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
|
||||||
|
0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
|
||||||
|
|
||||||
|
0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
|
||||||
|
0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
|
||||||
|
0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
|
||||||
|
0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
|
||||||
|
|
||||||
|
0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
|
||||||
|
0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
|
||||||
|
0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
|
||||||
|
0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
|
||||||
|
|
||||||
|
0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
|
||||||
|
0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
|
||||||
|
0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
|
||||||
|
0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
|
||||||
|
|
||||||
|
0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
|
||||||
|
0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
|
||||||
|
0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
|
||||||
|
0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char final_shuffle[16] = {
|
||||||
|
0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
|
||||||
|
0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* verschluesseln des neuen Passworts fuer keyed change password
|
||||||
|
* Verwendung:
|
||||||
|
* - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes)
|
||||||
|
* - shuffle neues passwort nach new (16 bytes)
|
||||||
|
* - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes:
|
||||||
|
* nwpassencrypt(old+0, new+0, out+0)
|
||||||
|
* nwpassencrypt(old+8, new+8, out+8)
|
||||||
|
* - NCP-Buffer aufbauen:
|
||||||
|
* 2 byte Laenge im Hi-Lo-Format
|
||||||
|
* 1 byte Funktion (0x4b)
|
||||||
|
* 8 byte (nwcrypt Ergebnis analog login/verify password)
|
||||||
|
* 2 byte Objecttype
|
||||||
|
* 1 byte Objectname-Laenge
|
||||||
|
* n byte Objectname
|
||||||
|
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
|
||||||
|
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encrypt the new password for keyed change password
|
||||||
|
* For info on how to use this function, look at ncp_change_login_passwd
|
||||||
|
* in ncplib.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
newpassencrypt(unsigned char *old, unsigned char *npwd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
int di, ax;
|
||||||
|
unsigned char *p, *bx;
|
||||||
|
unsigned char cl, dl, ch;
|
||||||
|
unsigned char copy[8];
|
||||||
|
|
||||||
|
memcpy(copy, npwd, 8);
|
||||||
|
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++)
|
||||||
|
{
|
||||||
|
cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4;
|
||||||
|
dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax];
|
||||||
|
copy[di] = cl | dl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = old[7];
|
||||||
|
for (bx = old + 7; bx > old; bx--)
|
||||||
|
{
|
||||||
|
*bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4);
|
||||||
|
}
|
||||||
|
*old = ((ch >> 4) & 0x0f) | (*old) << 4;
|
||||||
|
|
||||||
|
memset(npwd, 0, 8);
|
||||||
|
|
||||||
|
for (di = 0; di < 16; di++)
|
||||||
|
{
|
||||||
|
if (final_shuffle[di] & 1)
|
||||||
|
ch = ((copy[final_shuffle[di] / 2] >> 4) & 0x0f);
|
||||||
|
else
|
||||||
|
ch = copy[final_shuffle[di] / 2] & 0x0f;
|
||||||
|
npwd[di / 2] |= ((di & 1) ? ch << 4 : ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
2
nwcrypt.h
Executable file → Normal file
2
nwcrypt.h
Executable file → Normal file
@@ -5,3 +5,5 @@ extern void shuffle(unsigned char *lon,
|
|||||||
|
|
||||||
extern void nw_encrypt(unsigned char *fra,
|
extern void nw_encrypt(unsigned char *fra,
|
||||||
unsigned char *buf,unsigned char *til);
|
unsigned char *buf,unsigned char *til);
|
||||||
|
|
||||||
|
extern void newpassencrypt(unsigned char *old, unsigned char *npwd);
|
||||||
|
|||||||
11
nwdebug.c
Executable file → Normal file
11
nwdebug.c
Executable file → Normal file
@@ -1,4 +1,4 @@
|
|||||||
/* nwdebug.c 04-Apr-96 */
|
/* nwdebug.c 21-May-96 */
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
||||||
@@ -13,7 +13,7 @@ static int usage(void)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int func_debug(int argc, char *argv[])
|
int func_debug(int argc, char *argv[], int mode)
|
||||||
{
|
{
|
||||||
uint8 s[200];
|
uint8 s[200];
|
||||||
int module;
|
int module;
|
||||||
@@ -29,8 +29,11 @@ int func_debug(int argc, char *argv[])
|
|||||||
level = atoi(argv[2]);
|
level = atoi(argv[2]);
|
||||||
if (level < 0 || level > 99) return(usage());
|
if (level < 0 || level > 99) return(usage());
|
||||||
result = ncp_17_02(module, level);
|
result = ncp_17_02(module, level);
|
||||||
if (result < 0) fprintf(stderr, "set debug failed\n");
|
if (result < 0) {
|
||||||
else fprintf(stdout, "Debug level for %s changed from %d to %d\n",
|
fprintf(stderr, "set debug failed\n");
|
||||||
|
fprintf(stderr, "perhaps you did not enable FUNC_17_02_IS_DEBUG\n");
|
||||||
|
fprintf(stderr, "in mars_nwe/config.h ?!");
|
||||||
|
} else fprintf(stdout, "Debug level for %s changed from %d to %d\n",
|
||||||
s, result, level);
|
s, result, level);
|
||||||
return(result < 0 ? result : 0);
|
return(result < 0 ? result : 0);
|
||||||
}
|
}
|
||||||
|
|||||||
134
nwtests.c
Executable file → Normal file
134
nwtests.c
Executable file → Normal file
@@ -1,46 +1,104 @@
|
|||||||
/* nwtests.c 14-Mar-96 */
|
/* nwtests.c - small DOS utility tests */
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
|
||||||
****************************************************************/
|
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
static int usage(void)
|
static int tests_same_arg(char *a, char *b)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\t%s NCPSERV|NWCONN level\n", funcname);
|
while (*a || *b) {
|
||||||
fprintf(stderr, "\tlevel=0 .. 99\n" );
|
int ca = *a++;
|
||||||
|
int cb = *b++;
|
||||||
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
||||||
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
||||||
|
if (ca != cb) return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tests_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Usage: TESTS [NCP87C32ATTR|NCP87C32AUTO]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tests_get_current_drive(void)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
|
||||||
|
regs.h.ah = 0x19;
|
||||||
|
int86(0x21, ®s, ®s);
|
||||||
|
return((int)regs.h.al);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tests_current_dhandle(uint8 *dhandle)
|
||||||
|
{
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 flags = 0;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
drive = tests_get_current_drive();
|
||||||
|
if (get_drive_info((uint8)drive, &connid, dhandle, &flags))
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
|
||||||
|
|
||||||
int func_tests(int argc, char *argv[])
|
if (!connid || (flags & 0x80))
|
||||||
{
|
return(-1);
|
||||||
int level = ncp_17_02(NWCONN, 6);
|
|
||||||
int dirhandle = alloc_temp_dir_handle(0, "SYS:", 'd', NULL);
|
|
||||||
int result = -1;
|
|
||||||
uint8 *path = (argc < 2) ? "SYS:\\TMP" : argv[1];
|
|
||||||
if (dirhandle > -1) {
|
|
||||||
result = ncp_16_02(dirhandle, "SYSTEM/", NULL, NULL, NULL, NULL);
|
|
||||||
result = ncp_16_02(dirhandle, "SYSTEM", NULL, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
fprintf(stdout, "dirhandle=%d, result=%d\n", dirhandle, result);
|
|
||||||
result = redir_device_drive(0x4, "u:", path);
|
|
||||||
fprintf(stdout, "redir path=%s, result=%d\n", path, result);
|
|
||||||
|
|
||||||
path="Q1";
|
|
||||||
result = redir_device_drive(0x3, "LPT1", path);
|
|
||||||
fprintf(stdout, "redir path=%s, result=%d\n", path, result);
|
|
||||||
|
|
||||||
{
|
|
||||||
int k =-1;
|
|
||||||
uint8 devname[20];
|
|
||||||
uint8 remotename[130];
|
|
||||||
int devicetyp;
|
|
||||||
while ((result = list_redir(++k, &devicetyp, devname, remotename)) > -1){
|
|
||||||
fprintf(stdout, "index=%d, dev=%s(%d), %s result=%d\n",
|
|
||||||
k, devname, devicetyp, remotename, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (level > -1) (void) ncp_17_02(NWCONN, level);
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tests_ncp87c32attr(void)
|
||||||
|
{
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint32 attr = 0;
|
||||||
|
uint16 actual = 0;
|
||||||
|
uint16 handle_lo = 0;
|
||||||
|
uint16 handle_hi = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (tests_current_dhandle(&dhandle)) {
|
||||||
|
fprintf(stdout, "NCP87C32ATTR failed: current drive is not a network drive\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = c32_ncp87_obtain_rim_attributes("LOGIN.EXE",
|
||||||
|
(uint16)dhandle,
|
||||||
|
&attr,
|
||||||
|
&actual,
|
||||||
|
&handle_lo,
|
||||||
|
&handle_hi);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stdout, "NCP87C32ATTR failed rc=%d\n", rc);
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "NCP87C32ATTR LOGIN.EXE attr=%02lX handle=%04X:%04X actual=%04X\n",
|
||||||
|
attr & 0xffUL, handle_hi, handle_lo, actual);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tests_ncp87c32auto(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Kept as a compatibility alias for the former verbose test command.
|
||||||
|
* The production helper path is exercised by NCP87C32ATTR.
|
||||||
|
*/
|
||||||
|
return tests_ncp87c32attr();
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_tests(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
tests_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tests_same_arg(argv[1], "NCP87C32ATTR"))
|
||||||
|
return tests_ncp87c32attr();
|
||||||
|
|
||||||
|
if (tests_same_arg(argv[1], "NCP87C32AUTO"))
|
||||||
|
return tests_ncp87c32auto();
|
||||||
|
|
||||||
|
tests_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|||||||
BIN
opt/logo-small.png
Normal file
BIN
opt/logo-small.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 380 KiB |
BIN
opt/logo.png
Normal file
BIN
opt/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
253
remove.c
Normal file
253
remove.c
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
/* remove.c - Novell REMOVE-like DOS utility */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
#include "trustee.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef _A_NORMAL
|
||||||
|
#define _A_NORMAL 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int remove_last_rc = 0;
|
||||||
|
|
||||||
|
static void remove_usage_error(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Command line arguments violate grammar defined for REMOVE.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Usage: REMOVE [USER | GROUP] name [FROM path] [option]\n");
|
||||||
|
fprintf(stdout, "Options: /Subdirs | /Files\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int remove_one(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 objtype, char *objname, int forced_is_file)
|
||||||
|
{
|
||||||
|
uint16 old_rights = 0;
|
||||||
|
int is_dir;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
is_dir = forced_is_file ? 0 : trustee_path_is_dir(path);
|
||||||
|
|
||||||
|
rc = c32_ncp87_find_trustee_rights(path, dhandle, object_id, &old_rights,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
remove_last_rc = rc;
|
||||||
|
if (rc) {
|
||||||
|
if (rc == 0xff)
|
||||||
|
fprintf(stdout, "No trustee for the specified %s.\n", is_dir ? "directory" : "file");
|
||||||
|
else
|
||||||
|
fprintf(stdout, "Error scanning trustee list.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = c32_ncp87_delete_trustee_rights(path, dhandle, object_id,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
remove_last_rc = rc;
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stdout, "Error deleting trustee.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char header[300];
|
||||||
|
trustee_header_path(header, path, sizeof(header));
|
||||||
|
fprintf(stdout, "%s\n\n", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objtype == TRUSTEE_BINDERY_GROUP)
|
||||||
|
fprintf(stdout, "Group \"%s\" no longer a trustee to the specified %s.\n",
|
||||||
|
objname, is_dir ? "directory" : "file");
|
||||||
|
else
|
||||||
|
fprintf(stdout, "User \"%s\" no longer a trustee to the specified %s.\n",
|
||||||
|
objname, is_dir ? "directory" : "file");
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int remove_subdirs(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 objtype, char *objname, int *count)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char pattern[260];
|
||||||
|
char child[260];
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (remove_one(path, dhandle, object_id, objtype, objname, 0) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
|
||||||
|
trustee_join_path(pattern, path, "*.*", sizeof(pattern));
|
||||||
|
|
||||||
|
if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) {
|
||||||
|
do {
|
||||||
|
if ((ff.attrib & _A_SUBDIR) && !trustee_is_dot_dir(ff.name)) {
|
||||||
|
trustee_join_path(child, path, ff.name, sizeof(child));
|
||||||
|
if (remove_subdirs(child, dhandle, object_id, objtype, objname, count))
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int remove_files(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 objtype, char *objname, int *count)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char dir[260];
|
||||||
|
char pat[80];
|
||||||
|
char spec[260];
|
||||||
|
char target[260];
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (trustee_path_is_dir(path)) {
|
||||||
|
strmaxcpy(dir, path, sizeof(dir) - 1);
|
||||||
|
strmaxcpy(pat, "*.*", sizeof(pat) - 1);
|
||||||
|
} else if (trustee_path_has_wildcards(path)) {
|
||||||
|
trustee_parent_pattern(dir, pat, path, sizeof(dir), sizeof(pat));
|
||||||
|
} else {
|
||||||
|
if (remove_one(path, dhandle, object_id, objtype, objname, 1) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
trustee_join_path(spec, dir, pat, sizeof(spec));
|
||||||
|
if (_dos_findfirst(spec, _A_NORMAL | _A_HIDDEN | _A_SYSTEM | _A_ARCH, &ff) == 0) {
|
||||||
|
do {
|
||||||
|
if (!(ff.attrib & _A_SUBDIR)) {
|
||||||
|
trustee_join_path(target, dir, ff.name, sizeof(target));
|
||||||
|
if (remove_one(target, dhandle, object_id, objtype, objname, 1) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_remove(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
char *path = ".";
|
||||||
|
char *objname = NULL;
|
||||||
|
char objprint[48];
|
||||||
|
uint16 objtype = TRUSTEE_BINDERY_USER;
|
||||||
|
int objtype_given = 0;
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint32 object_id;
|
||||||
|
int use_subdirs = 0;
|
||||||
|
int use_files = 0;
|
||||||
|
int count = 0;
|
||||||
|
int i = 1;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc < 2 || trustee_is_help(argv[1])) {
|
||||||
|
if (argc < 2)
|
||||||
|
remove_usage_error();
|
||||||
|
remove_usage();
|
||||||
|
return(argc < 2 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < argc && trustee_same(argv[i], "USER")) {
|
||||||
|
objtype = TRUSTEE_BINDERY_USER;
|
||||||
|
objtype_given = 1;
|
||||||
|
i++;
|
||||||
|
} else if (i < argc && trustee_same(argv[i], "GROUP")) {
|
||||||
|
objtype = TRUSTEE_BINDERY_GROUP;
|
||||||
|
objtype_given = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc) {
|
||||||
|
remove_usage_error();
|
||||||
|
remove_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
objname = argv[i++];
|
||||||
|
|
||||||
|
if (i < argc && trustee_same(argv[i], "FROM")) {
|
||||||
|
i++;
|
||||||
|
if (i >= argc) {
|
||||||
|
remove_usage_error();
|
||||||
|
remove_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
path = argv[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < argc) {
|
||||||
|
if (!trustee_is_option(argv[i])) {
|
||||||
|
remove_usage_error();
|
||||||
|
remove_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_is_files_option(argv[i])) {
|
||||||
|
use_files = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_is_subdirs_option(argv[i])) {
|
||||||
|
use_subdirs = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_usage_error();
|
||||||
|
remove_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_files && use_subdirs) {
|
||||||
|
fprintf(stdout, "Remove cannot do both directories and files in a single pass.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_current_dhandle(&connid, &dhandle)) {
|
||||||
|
fprintf(stdout, "Error: Drive not mapped to network.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id = trustee_lookup_object(objname, &objtype, objtype_given);
|
||||||
|
if (!object_id) {
|
||||||
|
if (objtype_given && objtype == TRUSTEE_BINDERY_GROUP)
|
||||||
|
fprintf(stdout, "Group \"%s\" not found.\n", objname);
|
||||||
|
else if (objtype_given)
|
||||||
|
fprintf(stdout, "User \"%s\" not found.\n", objname);
|
||||||
|
else
|
||||||
|
fprintf(stdout, "User or group \"%s\" not found.\n", objname);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
trustee_upcopy(objprint, objname, sizeof(objprint));
|
||||||
|
|
||||||
|
if (use_subdirs)
|
||||||
|
rc = remove_subdirs(path, (uint16)dhandle, object_id, objtype, objprint, &count);
|
||||||
|
else if (use_files)
|
||||||
|
rc = remove_files(path, (uint16)dhandle, object_id, objtype, objprint, &count);
|
||||||
|
else {
|
||||||
|
rc = remove_one(path, (uint16)dhandle, object_id, objtype, objprint, 0);
|
||||||
|
if (!rc)
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_subdirs || (!use_files && !rc))
|
||||||
|
fprintf(stdout, "Trustee \"%s\" removed from %d directories.\n", objprint, count);
|
||||||
|
else if (use_files)
|
||||||
|
fprintf(stdout, "Trustee \"%s\" removed from %d files.\n", objprint, count);
|
||||||
|
|
||||||
|
return(rc ? (remove_last_rc ? remove_last_rc : 1) : 0);
|
||||||
|
}
|
||||||
301
revoke.c
Normal file
301
revoke.c
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
/* revoke.c - Novell REVOKE-like DOS utility */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
#include "trustee.h"
|
||||||
|
|
||||||
|
#ifndef _A_NORMAL
|
||||||
|
#define _A_NORMAL 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int revoke_last_rc = 0;
|
||||||
|
|
||||||
|
static void revoke_usage_error(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Command line arguments violate grammar defined for REVOKE.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void revoke_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Usage: REVOKE rightslist* [FOR path] FROM [USER|GROUP] name [options]\n");
|
||||||
|
fprintf(stdout, "Options: /SubDirectories | /Files\n\n");
|
||||||
|
fprintf(stdout, "286 Rights:\t\t386 Rights:\n");
|
||||||
|
fprintf(stdout, "---------------\t\t--------------------\n");
|
||||||
|
fprintf(stdout, "ALL = All\t\tALL = All\n");
|
||||||
|
fprintf(stdout, "R = Read\t\tS = Supervisor\n");
|
||||||
|
fprintf(stdout, "W = Write\t\tR = Read\n");
|
||||||
|
fprintf(stdout, "O = Open\t\tW = Write\n");
|
||||||
|
fprintf(stdout, "C = Create\t\tC = Create\n");
|
||||||
|
fprintf(stdout, "D = Delete\t\tE = Erase\n");
|
||||||
|
fprintf(stdout, "P = Parental\t\tM = Modify\n");
|
||||||
|
fprintf(stdout, "S = Search\t\tF = File Scan\n");
|
||||||
|
fprintf(stdout, "M = Modify\t\tA = Access Control\n");
|
||||||
|
fprintf(stdout, "\n* Use abbreviations listed above, separated by spaces.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int revoke_one(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 revoke_mask, int forced_is_file)
|
||||||
|
{
|
||||||
|
uint16 old_rights = 0;
|
||||||
|
uint16 new_rights;
|
||||||
|
int is_dir;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
is_dir = forced_is_file ? 0 : trustee_path_is_dir(path);
|
||||||
|
|
||||||
|
rc = c32_ncp87_find_trustee_rights(path, dhandle, object_id, &old_rights,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
revoke_last_rc = rc;
|
||||||
|
if (rc) {
|
||||||
|
if (rc == 0xff)
|
||||||
|
fprintf(stdout, "No trustee for the specified %s.\n", is_dir ? "directory" : "file");
|
||||||
|
else
|
||||||
|
fprintf(stdout, "Error scanning trustee list.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_rights = (uint16)(old_rights & ~revoke_mask);
|
||||||
|
|
||||||
|
if (new_rights == 0) {
|
||||||
|
rc = c32_ncp87_delete_trustee_rights(path, dhandle, object_id,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
revoke_last_rc = rc;
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stdout, "Error deleting trustee.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = c32_ncp87_add_trustee_rights(path, dhandle, object_id, new_rights,
|
||||||
|
0xffff, NULL, NULL, NULL);
|
||||||
|
revoke_last_rc = rc;
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stdout, "Fatal error revoking access rights.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char header[300];
|
||||||
|
char bracket[10];
|
||||||
|
trustee_header_path(header, path, sizeof(header));
|
||||||
|
trustee_rights_bracket(new_rights, bracket);
|
||||||
|
fprintf(stdout, "%s\n\n", header);
|
||||||
|
fprintf(stdout, "Trustee's access rights set to [%s]\n", bracket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int revoke_subdirs(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 revoke_mask, int *count)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char pattern[260];
|
||||||
|
char child[260];
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (revoke_one(path, dhandle, object_id, revoke_mask, 0) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
|
||||||
|
trustee_join_path(pattern, path, "*.*", sizeof(pattern));
|
||||||
|
|
||||||
|
if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) {
|
||||||
|
do {
|
||||||
|
if ((ff.attrib & _A_SUBDIR) && !trustee_is_dot_dir(ff.name)) {
|
||||||
|
trustee_join_path(child, path, ff.name, sizeof(child));
|
||||||
|
if (revoke_subdirs(child, dhandle, object_id, revoke_mask, count))
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int revoke_files(char *path, uint16 dhandle, uint32 object_id,
|
||||||
|
uint16 revoke_mask, int *count)
|
||||||
|
{
|
||||||
|
struct find_t ff;
|
||||||
|
char dir[260];
|
||||||
|
char pat[80];
|
||||||
|
char spec[260];
|
||||||
|
char target[260];
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (trustee_path_is_dir(path)) {
|
||||||
|
strmaxcpy(dir, path, sizeof(dir) - 1);
|
||||||
|
strmaxcpy(pat, "*.*", sizeof(pat) - 1);
|
||||||
|
} else if (trustee_path_has_wildcards(path)) {
|
||||||
|
trustee_parent_pattern(dir, pat, path, sizeof(dir), sizeof(pat));
|
||||||
|
} else {
|
||||||
|
if (revoke_one(path, dhandle, object_id, revoke_mask, 1) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
trustee_join_path(spec, dir, pat, sizeof(spec));
|
||||||
|
if (_dos_findfirst(spec, _A_NORMAL | _A_HIDDEN | _A_SYSTEM | _A_ARCH, &ff) == 0) {
|
||||||
|
do {
|
||||||
|
if (!(ff.attrib & _A_SUBDIR)) {
|
||||||
|
trustee_join_path(target, dir, ff.name, sizeof(target));
|
||||||
|
if (revoke_one(target, dhandle, object_id, revoke_mask, 1) == 0)
|
||||||
|
(*count)++;
|
||||||
|
else
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
} while (_dos_findnext(&ff) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_revoke(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
uint16 rights = 0;
|
||||||
|
char *path = ".";
|
||||||
|
char *objname = NULL;
|
||||||
|
char objprint[48];
|
||||||
|
uint16 objtype = TRUSTEE_BINDERY_USER;
|
||||||
|
int objtype_given = 0;
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint32 object_id;
|
||||||
|
int use_subdirs = 0;
|
||||||
|
int use_files = 0;
|
||||||
|
int count = 0;
|
||||||
|
int i = 1;
|
||||||
|
int have_rights = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc < 2 || trustee_is_help(argv[1])) {
|
||||||
|
if (argc < 2)
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(argc < 2 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < argc) {
|
||||||
|
if (trustee_same(argv[i], "FOR") || trustee_same(argv[i], "FROM"))
|
||||||
|
break;
|
||||||
|
if (trustee_is_option(argv[i]))
|
||||||
|
break;
|
||||||
|
if (trustee_parse_right_word(argv[i], &rights)) {
|
||||||
|
fprintf(stdout, "Invalid right specified.\n");
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
have_rights = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_rights || i >= argc) {
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(argv[i], "FOR")) {
|
||||||
|
i++;
|
||||||
|
if (i >= argc) {
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
path = argv[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc || !trustee_same(argv[i], "FROM")) {
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i < argc && trustee_same(argv[i], "USER")) {
|
||||||
|
objtype = TRUSTEE_BINDERY_USER;
|
||||||
|
objtype_given = 1;
|
||||||
|
i++;
|
||||||
|
} else if (i < argc && trustee_same(argv[i], "GROUP")) {
|
||||||
|
objtype = TRUSTEE_BINDERY_GROUP;
|
||||||
|
objtype_given = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc) {
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
objname = argv[i++];
|
||||||
|
|
||||||
|
while (i < argc) {
|
||||||
|
if (!trustee_is_option(argv[i])) {
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_is_files_option(argv[i])) {
|
||||||
|
use_files = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_is_subdirs_option(argv[i])) {
|
||||||
|
use_subdirs = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
revoke_usage_error();
|
||||||
|
revoke_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_files && use_subdirs) {
|
||||||
|
fprintf(stdout, "Revoke cannot do both directories and files in a single pass.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_current_dhandle(&connid, &dhandle)) {
|
||||||
|
fprintf(stdout, "Error: Drive not mapped to Network.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id = trustee_lookup_object(objname, &objtype, objtype_given);
|
||||||
|
if (!object_id) {
|
||||||
|
if (objtype_given && objtype == TRUSTEE_BINDERY_GROUP)
|
||||||
|
fprintf(stdout, "Group \"%s\" not found.\n", objname);
|
||||||
|
else if (objtype_given)
|
||||||
|
fprintf(stdout, "User \"%s\" not found.\n", objname);
|
||||||
|
else
|
||||||
|
fprintf(stdout, "User or group \"%s\" not found.\n", objname);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
trustee_upcopy(objprint, objname, sizeof(objprint));
|
||||||
|
|
||||||
|
if (use_subdirs)
|
||||||
|
rc = revoke_subdirs(path, (uint16)dhandle, object_id, rights, &count);
|
||||||
|
else if (use_files)
|
||||||
|
rc = revoke_files(path, (uint16)dhandle, object_id, rights, &count);
|
||||||
|
else {
|
||||||
|
rc = revoke_one(path, (uint16)dhandle, object_id, rights, 0);
|
||||||
|
if (!rc)
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_subdirs || (!use_files && !rc))
|
||||||
|
fprintf(stdout, "Rights for %d directories were changed for %s.\n", count, objprint);
|
||||||
|
else if (use_files)
|
||||||
|
fprintf(stdout, "Rights for %d files were changed for %s.\n", count, objprint);
|
||||||
|
|
||||||
|
return(rc ? (revoke_last_rc ? revoke_last_rc : 1) : 0);
|
||||||
|
}
|
||||||
271
rights.c
Normal file
271
rights.c
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
/* rights.c - Novell RIGHTS-like DOS utility, read-only v4 */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "c32ncp.h"
|
||||||
|
#include <dos.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef S_IFDIR
|
||||||
|
#define S_IFDIR 0040000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NW_RIGHT_S 0x01
|
||||||
|
#define NW_RIGHT_R 0x02
|
||||||
|
#define NW_RIGHT_W 0x04
|
||||||
|
#define NW_RIGHT_C 0x08
|
||||||
|
#define NW_RIGHT_E 0x10
|
||||||
|
#define NW_RIGHT_M 0x20
|
||||||
|
#define NW_RIGHT_F 0x40
|
||||||
|
#define NW_RIGHT_A 0x80
|
||||||
|
|
||||||
|
/* NCP effective-rights bits returned by NCP87 subfunction 29. */
|
||||||
|
#define NCP_RIGHT_READ 0x0001
|
||||||
|
#define NCP_RIGHT_WRITE 0x0002
|
||||||
|
#define NCP_RIGHT_OPEN 0x0004
|
||||||
|
#define NCP_RIGHT_CREATE 0x0008
|
||||||
|
#define NCP_RIGHT_DELETE 0x0010
|
||||||
|
#define NCP_RIGHT_OWNER 0x0020
|
||||||
|
#define NCP_RIGHT_SEARCH 0x0040
|
||||||
|
#define NCP_RIGHT_MODIFY 0x0080
|
||||||
|
#define NCP_RIGHT_SUPER 0x0100
|
||||||
|
|
||||||
|
static uint8 rights_map_ncp_mask(uint16 ncp_rights);
|
||||||
|
|
||||||
|
|
||||||
|
static void rights_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Usage: RIGHTS [path]\n\n");
|
||||||
|
fprintf(stdout, "Rights = All | Supervisor | Read | Write | Create | Erase\n");
|
||||||
|
fprintf(stdout, " Modify | File scan | Access Control\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rights_parent_path(char *dst, char *src, int max)
|
||||||
|
{
|
||||||
|
char tmp[260];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
tool_upcopy(tmp, src, sizeof(tmp));
|
||||||
|
|
||||||
|
p = strrchr(tmp, '\\');
|
||||||
|
if (!p) p = strrchr(tmp, ':');
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == ':') {
|
||||||
|
p++;
|
||||||
|
*p = '\0';
|
||||||
|
} else {
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
strmaxcpy(dst, tmp, max - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rights_path_is_dir(char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (tool_is_current_path(path))
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
if (stat(path, &st) == 0) {
|
||||||
|
if (st.st_mode & S_IFDIR)
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int rights_effective_mask(char *path, int is_dir, uint8 *mask)
|
||||||
|
{
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint8 eff = 0;
|
||||||
|
char usepath[260];
|
||||||
|
int newhandle;
|
||||||
|
uint16 ncp_rights = 0;
|
||||||
|
|
||||||
|
if (mask) *mask = 0;
|
||||||
|
|
||||||
|
if (tool_current_dhandle(&connid, &dhandle))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prefer the explicit Client32 NCP87 effective-rights request. This is
|
||||||
|
* the DOS Client32 equivalent of ncpfs ncp_get_eff_directory_rights().
|
||||||
|
* It works for both files and directories, so pass the requested path
|
||||||
|
* itself instead of mapping files to their parent directory.
|
||||||
|
*/
|
||||||
|
if (!c32_ncp87_get_effective_rights(tool_is_current_path(path) ? "" : path,
|
||||||
|
(uint16)dhandle,
|
||||||
|
&ncp_rights,
|
||||||
|
NULL, NULL, NULL)) {
|
||||||
|
if (mask) *mask = rights_map_ncp_mask(ncp_rights);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback for older requesters/paths: allocate a temporary directory
|
||||||
|
* handle and use the returned old-style effective-rights byte.
|
||||||
|
* This cannot directly target a file, so files are mapped to their parent.
|
||||||
|
*/
|
||||||
|
if (tool_is_current_path(path)) {
|
||||||
|
usepath[0] = '\0';
|
||||||
|
} else if (is_dir) {
|
||||||
|
tool_upcopy(usepath, path, sizeof(usepath));
|
||||||
|
} else {
|
||||||
|
rights_parent_path(usepath, path, sizeof(usepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
newhandle = alloc_temp_dir_handle(dhandle, usepath, 0, &eff);
|
||||||
|
if (newhandle < 0) {
|
||||||
|
if (usepath[0]) {
|
||||||
|
int subdir = 1;
|
||||||
|
int r = ncp_16_02(dhandle, (uint8 *)usepath, &subdir,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
if (r >= 0) {
|
||||||
|
eff = (uint8)r;
|
||||||
|
} else {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eff = 0xff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dealloc_dir_handle(newhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask) *mask = eff;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 rights_map_ncp_mask(uint16 ncp_rights)
|
||||||
|
{
|
||||||
|
uint8 mask = 0;
|
||||||
|
|
||||||
|
if (ncp_rights & NCP_RIGHT_SUPER) mask |= NW_RIGHT_S;
|
||||||
|
if (ncp_rights & NCP_RIGHT_READ) mask |= NW_RIGHT_R;
|
||||||
|
if (ncp_rights & NCP_RIGHT_WRITE) mask |= NW_RIGHT_W;
|
||||||
|
if (ncp_rights & NCP_RIGHT_CREATE) mask |= NW_RIGHT_C;
|
||||||
|
if (ncp_rights & NCP_RIGHT_DELETE) mask |= NW_RIGHT_E;
|
||||||
|
if (ncp_rights & NCP_RIGHT_MODIFY) mask |= NW_RIGHT_M;
|
||||||
|
if (ncp_rights & NCP_RIGHT_SEARCH) mask |= NW_RIGHT_F;
|
||||||
|
if (ncp_rights & NCP_RIGHT_OWNER) mask |= NW_RIGHT_A;
|
||||||
|
|
||||||
|
return(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rights_mask_string(uint8 mask, char *out)
|
||||||
|
{
|
||||||
|
out[0] = (mask & NW_RIGHT_S) ? 'S' : '-';
|
||||||
|
out[1] = (mask & NW_RIGHT_R) ? 'R' : '-';
|
||||||
|
out[2] = (mask & NW_RIGHT_W) ? 'W' : '-';
|
||||||
|
out[3] = (mask & NW_RIGHT_C) ? 'C' : '-';
|
||||||
|
out[4] = (mask & NW_RIGHT_E) ? 'E' : '-';
|
||||||
|
out[5] = (mask & NW_RIGHT_M) ? 'M' : '-';
|
||||||
|
out[6] = (mask & NW_RIGHT_F) ? 'F' : '-';
|
||||||
|
out[7] = (mask & NW_RIGHT_A) ? 'A' : '-';
|
||||||
|
out[8] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Novell RIGHTS layout:
|
||||||
|
* - lines with star: two leading blanks, star, blank, text
|
||||||
|
* - lines without star: four leading blanks, text
|
||||||
|
* Keep the right-column letter at a fixed-ish DOS-screen position.
|
||||||
|
*/
|
||||||
|
static void rights_print_line(int have, int star, char *text, char letter)
|
||||||
|
{
|
||||||
|
(void)have;
|
||||||
|
|
||||||
|
if (star)
|
||||||
|
fprintf(stdout, " * %-43s(%c)\n", text, letter);
|
||||||
|
else
|
||||||
|
fprintf(stdout, " %-43s(%c)\n", text, letter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rights_display(char *path, int is_dir, uint8 mask)
|
||||||
|
{
|
||||||
|
char hdr[300];
|
||||||
|
char mstr[10];
|
||||||
|
|
||||||
|
tool_header_path(hdr, path, sizeof(hdr));
|
||||||
|
rights_mask_string(mask, mstr);
|
||||||
|
|
||||||
|
fprintf(stdout, "%s\n", hdr);
|
||||||
|
|
||||||
|
if (is_dir)
|
||||||
|
fprintf(stdout, "Your Effective Rights for this directory are [%s]\n", mstr);
|
||||||
|
else
|
||||||
|
fprintf(stdout, "Your Effective Rights for this file are [%s]\n", mstr);
|
||||||
|
|
||||||
|
if (is_dir) {
|
||||||
|
rights_print_line(mask & NW_RIGHT_S, 0, "You have Supervisor Rights to Directory.", 'S');
|
||||||
|
rights_print_line(mask & NW_RIGHT_R, 1, "May Read from File.", 'R');
|
||||||
|
rights_print_line(mask & NW_RIGHT_W, 1, "May Write to File.", 'W');
|
||||||
|
rights_print_line(mask & NW_RIGHT_C, 0, "May Create Subdirectories and Files.", 'C');
|
||||||
|
rights_print_line(mask & NW_RIGHT_E, 0, "May Erase Directory.", 'E');
|
||||||
|
rights_print_line(mask & NW_RIGHT_M, 0, "May Modify Directory.", 'M');
|
||||||
|
rights_print_line(mask & NW_RIGHT_F, 0, "May Scan for Files.", 'F');
|
||||||
|
rights_print_line(mask & NW_RIGHT_A, 0, "May Change Access Control.", 'A');
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, " * Has no effect on directory.\n\n");
|
||||||
|
fprintf(stdout, " Entries in Directory May Inherit [%s] rights.\n", mstr);
|
||||||
|
if (mask == 0xff)
|
||||||
|
fprintf(stdout, " You have ALL RIGHTS to Directory Entry.\n");
|
||||||
|
} else {
|
||||||
|
rights_print_line(mask & NW_RIGHT_S, 0, "You have Supervisor Rights to File.", 'S');
|
||||||
|
rights_print_line(mask & NW_RIGHT_R, 0, "May Read from File.", 'R');
|
||||||
|
rights_print_line(mask & NW_RIGHT_W, 0, "May Write to File.", 'W');
|
||||||
|
rights_print_line(mask & NW_RIGHT_C, 1, "May Create Subdirectories and Files.", 'C');
|
||||||
|
rights_print_line(mask & NW_RIGHT_E, 0, "May Erase File.", 'E');
|
||||||
|
rights_print_line(mask & NW_RIGHT_M, 0, "May Modify File.", 'M');
|
||||||
|
rights_print_line(mask & NW_RIGHT_F, 0, "May Scan for File.", 'F');
|
||||||
|
rights_print_line(mask & NW_RIGHT_A, 0, "May Change Access Control.", 'A');
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, " * Create is necessary to salvage a file that has been deleted.\n\n");
|
||||||
|
if (mask == 0xff)
|
||||||
|
fprintf(stdout, " You have ALL RIGHTS to Directory Entry.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_rights(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
char *path = ".";
|
||||||
|
uint8 mask = 0;
|
||||||
|
int is_dir;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
rights_usage();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
if (tool_is_help_arg(argv[1])) {
|
||||||
|
rights_usage();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
path = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
is_dir = rights_path_is_dir(path);
|
||||||
|
|
||||||
|
if (rights_effective_mask(path, is_dir, &mask)) {
|
||||||
|
fprintf(stdout, "Specified path not locatable.\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rights_display(path, is_dir, mask);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
120
slist.c
Executable file → Normal file
120
slist.c
Executable file → Normal file
@@ -1,15 +1,115 @@
|
|||||||
/* map.c 12-Jan-96 */
|
/* slist.c - list known NetWare file servers, DOS mars-dosutils version */
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
|
||||||
****************************************************************/
|
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
int func_slist(int argc, char *argv[])
|
#define NCP_BINDERY_FSERVER 0x0004
|
||||||
|
|
||||||
|
static int usage(void)
|
||||||
{
|
{
|
||||||
|
fprintf(stdout, "Usage: SLIST [Server] [/Continue]\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int same_arg(char *a, char *b)
|
||||||
|
{
|
||||||
|
while (*a || *b) {
|
||||||
|
int ca = *a++;
|
||||||
|
int cb = *b++;
|
||||||
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
||||||
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
||||||
|
if (ca != cb) return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_help_arg(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(same_arg(s, "/?") || same_arg(s, "-?") || same_arg(s, "?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long node_to_number(uint8 *addr)
|
||||||
|
{
|
||||||
|
unsigned long n = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 4; i < 10; i++)
|
||||||
|
n = (n << 8) + addr[i];
|
||||||
|
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_net_node_status(uint8 *addr, int is_default)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "[%08lX][%12lu]%s",
|
||||||
|
(unsigned long)GET_BE32(addr),
|
||||||
|
node_to_number(addr),
|
||||||
|
is_default ? "Default" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_slist(int argc, char *argv[], int mode)
|
||||||
|
{
|
||||||
|
BINDERY_OBJECT obj;
|
||||||
|
uint32 last_id = MAX_U32;
|
||||||
|
uint8 pattern[50];
|
||||||
|
int found = 0;
|
||||||
|
int result;
|
||||||
|
int i;
|
||||||
|
int continuous = 0;
|
||||||
|
int line_count = 0;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
strcpy(pattern, "*");
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (is_help_arg(argv[i])) return(usage());
|
||||||
|
|
||||||
|
if (argv[i][0] == '/' || argv[i][0] == '-') {
|
||||||
|
if (same_arg(argv[i], "/C") || same_arg(argv[i], "/CONTINUE") ||
|
||||||
|
same_arg(argv[i], "-C") || same_arg(argv[i], "-CONTINUE")) {
|
||||||
|
continuous = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return(usage());
|
||||||
|
}
|
||||||
|
|
||||||
|
strmaxcpy(pattern, argv[i], sizeof(pattern) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
upstr(pattern);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Novell-like layout from the DOS client:
|
||||||
|
* Known NetWare File Servers Network Node Address Status
|
||||||
|
* ------------------------- -------- -------------------
|
||||||
|
*/
|
||||||
|
fprintf(stdout, "%-44sNetwork Node Address Status\n",
|
||||||
|
"Known NetWare File Servers");
|
||||||
|
fprintf(stdout, "%-44s------- ----------- ------\n",
|
||||||
|
"--------------------------");
|
||||||
|
|
||||||
|
while ((result = ncp_17_37(last_id, NCP_BINDERY_FSERVER,
|
||||||
|
pattern, &obj)) == 0) {
|
||||||
|
NW_PROPERTY prop;
|
||||||
|
|
||||||
|
found++;
|
||||||
|
last_id = obj.object_id;
|
||||||
|
|
||||||
|
fprintf(stdout, "%-44s", obj.object_name);
|
||||||
|
|
||||||
|
if (!ncp_17_3d(NCP_BINDERY_FSERVER, obj.object_name,
|
||||||
|
1, "NET_ADDRESS", &prop)) {
|
||||||
|
print_net_node_status(prop.value, found == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
tool_page_line(&line_count, &continuous);
|
||||||
|
|
||||||
|
if (last_id == MAX_U32) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\nTotal of %d file servers found\n", found);
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|||||||
4
teste.c
Executable file → Normal file
4
teste.c
Executable file → Normal file
@@ -22,11 +22,11 @@ int main()
|
|||||||
close(fd);
|
close(fd);
|
||||||
_chmod(fn, 1, _chmod(fn, 0) | 0x80 );
|
_chmod(fn, 1, _chmod(fn, 0) | 0x80 );
|
||||||
stat(fn, &stbuff);
|
stat(fn, &stbuff);
|
||||||
printf("Filesize <20>ber stat =%ld\n", stbuff.st_size);
|
printf("Filesize <20>ber stat =%ld\n", stbuff.st_size);
|
||||||
fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE);
|
fd = open(fn, O_RDWR | O_BINARY |O_DENYNONE);
|
||||||
|
|
||||||
offset = lseek(fd, 0L, SEEK_END);
|
offset = lseek(fd, 0L, SEEK_END);
|
||||||
printf("Filesize <20>ber lseek =%ld\n", offset);
|
printf("Filesize <20>ber lseek =%ld\n", offset);
|
||||||
write(fd, buff, strlen(buff));
|
write(fd, buff, strlen(buff));
|
||||||
|
|
||||||
lseek(fd, 0L, SEEK_SET);
|
lseek(fd, 0L, SEEK_SET);
|
||||||
|
|||||||
425
tools.c
Executable file → Normal file
425
tools.c
Executable file → Normal file
@@ -5,21 +5,66 @@
|
|||||||
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
/*
|
||||||
|
* Borland C compatibility wrappers used by the historical mars-nwe DOS tools.
|
||||||
|
* Open Watcom does not provide getcurdir()/setdisk() under these Borland names.
|
||||||
|
*/
|
||||||
|
int getcurdir(int drive, char *directory)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
SREGS sregs;
|
||||||
|
|
||||||
|
regs.h.ah = 0x47; /* DOS: get current directory */
|
||||||
|
regs.h.dl = (unsigned char)drive; /* 0=current, 1=A:, 2=B:, ... */
|
||||||
|
sregs.ds = FP_SEG(directory);
|
||||||
|
regs.x.si = FP_OFF(directory);
|
||||||
|
intdosx(®s, ®s, &sregs);
|
||||||
|
return(regs.x.cflag ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setdisk(int drive)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
|
||||||
|
regs.h.ah = 0x0e; /* DOS: select default drive */
|
||||||
|
regs.h.dl = (unsigned char)drive; /* 0=A:, 1=B:, ... */
|
||||||
|
intdos(®s, ®s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int key_pressed(void)
|
int key_pressed(void)
|
||||||
{
|
{
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
/*
|
||||||
|
* Open Watcom's WORDREGS does not expose x.flags. The old Borland
|
||||||
|
* code checked the BIOS INT 16h ZF bit after AH=01h. Open Watcom's
|
||||||
|
* bios.h provides _bios_keybrd(), which wraps the same BIOS keyboard
|
||||||
|
* service and returns 0 when no key is waiting.
|
||||||
|
*/
|
||||||
|
return(_bios_keybrd(_KEYBRD_READY) != 0);
|
||||||
|
#else
|
||||||
REGS regsin, regsout;
|
REGS regsin, regsout;
|
||||||
regsin.h.ah = 0x01; /* read key-press */
|
regsin.h.ah = 0x01; /* read key-press */
|
||||||
int86(0x16, ®sin, ®sout);
|
int86(0x16, ®sin, ®sout);
|
||||||
return((regsout.x.flags & 0x40) ? 0 : 1); /* zeroflag != 0 */
|
return((regsout.x.flags & 0x40) ? 0 : 1); /* zeroflag != 0 */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_kb(void)
|
void clear_kb(void)
|
||||||
{
|
{
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
while (key_pressed()) {
|
||||||
|
(void)_bios_keybrd(_KEYBRD_READ);
|
||||||
|
}
|
||||||
|
#else
|
||||||
REGS regsin, regsout;
|
REGS regsin, regsout;
|
||||||
while (key_pressed()) { /* zeroflag != 0 */
|
while (key_pressed()) { /* zeroflag != 0 */
|
||||||
regsin.h.ah = 0x00; /* read key-press */
|
regsin.h.ah = 0x00; /* read key-press */
|
||||||
int86(0x16, ®sin, ®sout);
|
int86(0x16, ®sin, ®sout);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int ask_user(char *p, ...)
|
int ask_user(char *p, ...)
|
||||||
@@ -48,6 +93,31 @@ int ask_user(char *p, ...)
|
|||||||
return(flag);
|
return(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *xmalloc(uint size)
|
||||||
|
{
|
||||||
|
char *p = (size) ? (char *)malloc(size) : (char*)NULL;
|
||||||
|
if (p == (char *)NULL && size){
|
||||||
|
fprintf(stderr, "not enough core, need %d Bytes\n", size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xcmalloc(uint size)
|
||||||
|
{
|
||||||
|
char *p = xmalloc(size);
|
||||||
|
if (size) memset(p, 0, size);
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void x_x_xfree(char **p)
|
||||||
|
{
|
||||||
|
if (*p != (char *)NULL){
|
||||||
|
free(*p);
|
||||||
|
*p = (char*)NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int strmaxcpy(char *dest, char *source, int len)
|
int strmaxcpy(char *dest, char *source, int len)
|
||||||
/* copied max. len chars + '\0' Byte */
|
/* copied max. len chars + '\0' Byte */
|
||||||
{
|
{
|
||||||
@@ -69,6 +139,18 @@ char *xadd_char(char *s, int c, int maxlen)
|
|||||||
return(s);
|
return(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8 down_char(uint8 ch)
|
||||||
|
{
|
||||||
|
if (ch > 64 && ch < 91) return(ch + 32);
|
||||||
|
switch(ch){
|
||||||
|
case 142: ch = 132; break;
|
||||||
|
case 153: ch = 148; break;
|
||||||
|
case 154: ch = 129; break;
|
||||||
|
default :break;
|
||||||
|
}
|
||||||
|
return(ch);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8 up_char(uint8 ch)
|
static uint8 up_char(uint8 ch)
|
||||||
{
|
{
|
||||||
if (ch > 96 && ch < 123) return(ch - 32);
|
if (ch > 96 && ch < 123) return(ch - 32);
|
||||||
@@ -88,6 +170,64 @@ uint8 *upstr(uint8 *s)
|
|||||||
return(s);
|
return(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deb(uint8 *s)
|
||||||
|
{
|
||||||
|
if (!s || !*s) return;
|
||||||
|
else {
|
||||||
|
uint8 *p = s + strlen(s);
|
||||||
|
while (p > s && (*--p==32 || *p==9));;
|
||||||
|
if (*p==32 || *p==9) *p='\0';
|
||||||
|
else *(p+1) = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void leb(uint8 *s)
|
||||||
|
{
|
||||||
|
if (!s || !*s || (*s != 32 && *s != 9)) return;
|
||||||
|
else {
|
||||||
|
uint8 *p = s;
|
||||||
|
for (;*p && *p!=32 && *p!=9;p++);;
|
||||||
|
strcpy(s, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void korrpath(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return;
|
||||||
|
for (;*s;s++) {
|
||||||
|
if (*s=='\\') *s='/';
|
||||||
|
else *s=down_char(*s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_path_fn(char *s, char *p, char *fn)
|
||||||
|
{
|
||||||
|
int j= strlen(s);
|
||||||
|
if (p != (char *)NULL) p[0] = 0;
|
||||||
|
if (fn != (char*) NULL) fn[0] = 0;
|
||||||
|
if (!j) return;
|
||||||
|
if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0) ) ) {
|
||||||
|
if (p != (char *)NULL) {
|
||||||
|
strcpy(p, s);
|
||||||
|
strcat(p, "/");
|
||||||
|
}
|
||||||
|
if (fn != (char *)NULL) fn[0] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (j--){
|
||||||
|
if ((s[j] == '/') || (s[j] == ':') ) {
|
||||||
|
if (fn != (char *)NULL) strcpy(fn, s+j+1);
|
||||||
|
if (p != (char *)NULL) {
|
||||||
|
strncpy(p, s, j+1);
|
||||||
|
p[j+1] = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fn != (char *)NULL) strcpy(fn, s); /* no path */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16 adr1;
|
uint16 adr1;
|
||||||
uint16 adr2;
|
uint16 adr2;
|
||||||
@@ -188,7 +328,7 @@ int putglobenv(char *option)
|
|||||||
}
|
}
|
||||||
search=nextp;
|
search=nextp;
|
||||||
}
|
}
|
||||||
/* nicht gefunden , nun eintragen, falls m”glich */
|
/* nicht gefunden , nun eintragen, falls m�glich */
|
||||||
if (*(equal+1) && optionlen < maxenvsize - aktenvsize) {
|
if (*(equal+1) && optionlen < maxenvsize - aktenvsize) {
|
||||||
strcpy(search, option);
|
strcpy(search, option);
|
||||||
*(search+optionlen+1) = '\0'; /* letzter Eintrag '\0' nicht vergessen */
|
*(search+optionlen+1) = '\0'; /* letzter Eintrag '\0' nicht vergessen */
|
||||||
@@ -199,3 +339,286 @@ int putglobenv(char *option)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int tool_page_line(int *line_count, int *continuous)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!line_count || !continuous)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (*continuous)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
(*line_count)++;
|
||||||
|
if (*line_count < 24)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
fprintf(stdout, "Press any key to continue ('C' for continue)");
|
||||||
|
fflush(stdout);
|
||||||
|
ch = getch();
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
if (ch == 'c' || ch == 'C')
|
||||||
|
*continuous = 1;
|
||||||
|
|
||||||
|
*line_count = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Shared helpers for the newer DOS utility frontends.
|
||||||
|
*
|
||||||
|
* These deliberately stay in tools.c instead of in grant/revoke/remove/
|
||||||
|
* rights/flagdir so the current multicall binary and possible future
|
||||||
|
* grouped multicall binaries can reuse the same code without dragging in
|
||||||
|
* command-specific modules.
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
int tool_strsame(char *a, char *b)
|
||||||
|
{
|
||||||
|
if (!a) a = "";
|
||||||
|
if (!b) b = "";
|
||||||
|
|
||||||
|
while (*a || *b) {
|
||||||
|
int ca = *a++;
|
||||||
|
int cb = *b++;
|
||||||
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
||||||
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
||||||
|
if (ca != cb) return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_help_arg(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(tool_strsame(s, "/?") || tool_strsame(s, "-?") ||
|
||||||
|
tool_strsame(s, "?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_option(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(s[0] == '/' || s[0] == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_files_option(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(tool_strsame(s, "/FILES") || tool_strsame(s, "-FILES") ||
|
||||||
|
tool_strsame(s, "/F") || tool_strsame(s, "-F"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_subdirs_option(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(tool_strsame(s, "/SUBDIRS") || tool_strsame(s, "-SUBDIRS") ||
|
||||||
|
tool_strsame(s, "/SUBDIRECTORIES") ||
|
||||||
|
tool_strsame(s, "-SUBDIRECTORIES") ||
|
||||||
|
tool_strsame(s, "/S") || tool_strsame(s, "-S"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_get_current_drive(void)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
|
||||||
|
regs.h.ah = 0x19;
|
||||||
|
int86(0x21, ®s, ®s);
|
||||||
|
return((int)regs.h.al);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_current_dhandle(uint8 *connid, uint8 *dhandle)
|
||||||
|
{
|
||||||
|
uint8 flags = 0;
|
||||||
|
int drive = tool_get_current_drive();
|
||||||
|
|
||||||
|
if (get_drive_info((uint8)drive, connid, dhandle, &flags))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (!*connid || (flags & 0x80))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_current_prefix(char *out, int max)
|
||||||
|
{
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
uint8 flags = 0;
|
||||||
|
int drive;
|
||||||
|
char server[52];
|
||||||
|
char dpath[260];
|
||||||
|
char volume[32];
|
||||||
|
char *p;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!out || max < 8)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
out[0] = '\0';
|
||||||
|
|
||||||
|
drive = tool_get_current_drive();
|
||||||
|
if (get_drive_info((uint8)drive, &connid, &dhandle, &flags))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (!connid || (flags & 0x80))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
server[0] = '\0';
|
||||||
|
if (get_fs_name(connid, server))
|
||||||
|
server[0] = '\0';
|
||||||
|
|
||||||
|
dpath[0] = '\0';
|
||||||
|
if (get_dir_path(dhandle, dpath) || !dpath[0])
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
p = strchr(dpath, ':');
|
||||||
|
if (!p)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
while (dpath + i < p && i < (int)sizeof(volume) - 1) {
|
||||||
|
volume[i] = dpath[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
volume[i] = '\0';
|
||||||
|
|
||||||
|
if (!volume[0])
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (server[0])
|
||||||
|
sprintf(out, "%s/%s:", server, volume);
|
||||||
|
else
|
||||||
|
sprintf(out, "%s:", volume);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_current_path(char *path)
|
||||||
|
{
|
||||||
|
if (!path || !*path) return(1);
|
||||||
|
if (tool_strsame(path, ".")) return(1);
|
||||||
|
if (tool_strsame(path, ".\\")) return(1);
|
||||||
|
if (tool_strsame(path, "./")) return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tool_upcopy(char *dst, char *src, int max)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!src) src = "";
|
||||||
|
|
||||||
|
while (*src && i < max - 1) {
|
||||||
|
char c = *src++;
|
||||||
|
if (c == '/') c = '\\';
|
||||||
|
if (c >= 'a' && c <= 'z') c -= 32;
|
||||||
|
dst[i++] = c;
|
||||||
|
}
|
||||||
|
dst[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tool_basename(char *dst, char *src, int max)
|
||||||
|
{
|
||||||
|
char up[260];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
tool_upcopy(up, src, sizeof(up));
|
||||||
|
p = strrchr(up, '\\');
|
||||||
|
if (!p) p = strrchr(up, ':');
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
strmaxcpy(dst, p + 1, max - 1);
|
||||||
|
else
|
||||||
|
strmaxcpy(dst, up, max - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tool_header_path(char *out, char *path, int max)
|
||||||
|
{
|
||||||
|
char prefix[90];
|
||||||
|
char up[260];
|
||||||
|
|
||||||
|
if (tool_current_prefix(prefix, sizeof(prefix)))
|
||||||
|
prefix[0] = '\0';
|
||||||
|
|
||||||
|
if (tool_is_current_path(path)) {
|
||||||
|
strmaxcpy(out, prefix, max - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tool_upcopy(up, path, sizeof(up));
|
||||||
|
strmaxcpy(out, prefix, max - 1);
|
||||||
|
if ((int)(strlen(out) + strlen(up)) < max - 1)
|
||||||
|
strcat(out, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_is_dot_dir(char *name)
|
||||||
|
{
|
||||||
|
if (!name) return(0);
|
||||||
|
if (name[0] == '.' && name[1] == '\0') return(1);
|
||||||
|
if (name[0] == '.' && name[1] == '.' && name[2] == '\0') return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tool_join_path(char *out, char *base, char *name, int max)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
out[0] = '\0';
|
||||||
|
strmaxcpy(out, base, max - 1);
|
||||||
|
len = strlen(out);
|
||||||
|
|
||||||
|
if (len > 0 && out[len - 1] != '\\' && out[len - 1] != '/' &&
|
||||||
|
out[len - 1] != ':') {
|
||||||
|
if (len < max - 1) {
|
||||||
|
out[len++] = '\\';
|
||||||
|
out[len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int)(strlen(out) + strlen(name)) < max - 1)
|
||||||
|
strcat(out, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tool_has_wildcards(char *path)
|
||||||
|
{
|
||||||
|
if (!path) return(0);
|
||||||
|
while (*path) {
|
||||||
|
if (*path == '*' || *path == '?') return(1);
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tool_parent_pattern(char *dir, char *pattern, char *path,
|
||||||
|
int maxdir, int maxpat)
|
||||||
|
{
|
||||||
|
char tmp[260];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
tool_upcopy(tmp, path, sizeof(tmp));
|
||||||
|
p = strrchr(tmp, '\\');
|
||||||
|
if (!p) p = strrchr(tmp, ':');
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
if (*p == ':') {
|
||||||
|
p++;
|
||||||
|
strmaxcpy(pattern, p, maxpat - 1);
|
||||||
|
*p = '\0';
|
||||||
|
strmaxcpy(dir, tmp, maxdir - 1);
|
||||||
|
} else {
|
||||||
|
strmaxcpy(pattern, p + 1, maxpat - 1);
|
||||||
|
*p = '\0';
|
||||||
|
strmaxcpy(dir, tmp, maxdir - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
strmaxcpy(dir, ".", maxdir - 1);
|
||||||
|
strmaxcpy(pattern, tmp, maxpat - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pattern[0])
|
||||||
|
strmaxcpy(pattern, "*.*", maxpat - 1);
|
||||||
|
}
|
||||||
|
|||||||
165
trustee.c
Normal file
165
trustee.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/* trustee.c - shared helpers for GRANT/REVOKE/REMOVE style tools */
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
#include "trustee.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef S_IFDIR
|
||||||
|
#define S_IFDIR 0040000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int trustee_same(char *a, char *b) { return(tool_strsame(a, b)); }
|
||||||
|
int trustee_is_help(char *s) { return(tool_is_help_arg(s)); }
|
||||||
|
int trustee_is_option(char *s) { return(tool_is_option(s)); }
|
||||||
|
int trustee_current_dhandle(uint8 *connid, uint8 *dhandle)
|
||||||
|
{
|
||||||
|
return(tool_current_dhandle(connid, dhandle));
|
||||||
|
}
|
||||||
|
void trustee_upcopy(char *dst, char *src, int max) { tool_upcopy(dst, src, max); }
|
||||||
|
void trustee_basename(char *dst, char *src, int max)
|
||||||
|
{
|
||||||
|
tool_basename(dst, src, max);
|
||||||
|
}
|
||||||
|
void trustee_header_path(char *out, char *path, int max)
|
||||||
|
{
|
||||||
|
tool_header_path(out, path, max);
|
||||||
|
}
|
||||||
|
void trustee_join_path(char *out, char *base, char *name, int max)
|
||||||
|
{
|
||||||
|
tool_join_path(out, base, name, max);
|
||||||
|
}
|
||||||
|
int trustee_is_dot_dir(char *name) { return(tool_is_dot_dir(name)); }
|
||||||
|
int trustee_path_has_wildcards(char *path) { return(tool_has_wildcards(path)); }
|
||||||
|
void trustee_parent_pattern(char *dir, char *pattern, char *path,
|
||||||
|
int maxdir, int maxpat)
|
||||||
|
{
|
||||||
|
tool_parent_pattern(dir, pattern, path, maxdir, maxpat);
|
||||||
|
}
|
||||||
|
|
||||||
|
int trustee_is_subdirs_option(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(trustee_same(s, "/SUBDIRS") || trustee_same(s, "-SUBDIRS") ||
|
||||||
|
trustee_same(s, "/SUBDIRECTORIES") || trustee_same(s, "-SUBDIRECTORIES") ||
|
||||||
|
trustee_same(s, "/S") || trustee_same(s, "-S"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int trustee_is_files_option(char *s)
|
||||||
|
{
|
||||||
|
if (!s) return(0);
|
||||||
|
return(trustee_same(s, "/FILES") || trustee_same(s, "-FILES") ||
|
||||||
|
trustee_same(s, "/F") || trustee_same(s, "-F"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int trustee_parse_right_word(char *s, uint16 *rights)
|
||||||
|
{
|
||||||
|
if (trustee_same(s, "ALL")) {
|
||||||
|
*rights = TRUSTEE_RIGHT_ALL_386;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "N") || trustee_same(s, "NONE")) {
|
||||||
|
*rights = TRUSTEE_RIGHT_ALL_386;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "S") || trustee_same(s, "SUPERVISOR")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_SUPER;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "R") || trustee_same(s, "READ")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_READ;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "W") || trustee_same(s, "WRITE")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_WRITE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "C") || trustee_same(s, "CREATE")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_CREATE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "E") || trustee_same(s, "ERASE") ||
|
||||||
|
trustee_same(s, "D") || trustee_same(s, "DELETE")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_DELETE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "M") || trustee_same(s, "MODIFY")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_MODIFY;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "F") || trustee_same(s, "FILESCAN") ||
|
||||||
|
trustee_same(s, "FILE") || trustee_same(s, "SCAN")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_SEARCH;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trustee_same(s, "A") || trustee_same(s, "ACCESS") ||
|
||||||
|
trustee_same(s, "CONTROL") || trustee_same(s, "ACCESSCONTROL")) {
|
||||||
|
*rights |= TRUSTEE_RIGHT_OWNER;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void trustee_rights_bracket(uint16 rights, char *out)
|
||||||
|
{
|
||||||
|
out[0] = (rights & TRUSTEE_RIGHT_SUPER) ? 'S' : ' ';
|
||||||
|
out[1] = (rights & TRUSTEE_RIGHT_READ) ? 'R' : ' ';
|
||||||
|
out[2] = (rights & TRUSTEE_RIGHT_WRITE) ? 'W' : ' ';
|
||||||
|
out[3] = (rights & TRUSTEE_RIGHT_CREATE) ? 'C' : ' ';
|
||||||
|
out[4] = (rights & TRUSTEE_RIGHT_DELETE) ? 'E' : ' ';
|
||||||
|
out[5] = (rights & TRUSTEE_RIGHT_MODIFY) ? 'M' : ' ';
|
||||||
|
out[6] = (rights & TRUSTEE_RIGHT_SEARCH) ? 'F' : ' ';
|
||||||
|
out[7] = (rights & TRUSTEE_RIGHT_OWNER) ? 'A' : ' ';
|
||||||
|
out[8] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 trustee_lookup_object(char *name, uint16 *objtype, int objtype_given)
|
||||||
|
{
|
||||||
|
uint8 namebuf[48];
|
||||||
|
uint32 object_id;
|
||||||
|
|
||||||
|
strmaxcpy(namebuf, name, sizeof(namebuf) - 1);
|
||||||
|
upstr(namebuf);
|
||||||
|
|
||||||
|
if (objtype_given) {
|
||||||
|
return(ncp_17_35(namebuf, *objtype));
|
||||||
|
}
|
||||||
|
|
||||||
|
*objtype = TRUSTEE_BINDERY_USER;
|
||||||
|
object_id = ncp_17_35(namebuf, TRUSTEE_BINDERY_USER);
|
||||||
|
if (object_id)
|
||||||
|
return(object_id);
|
||||||
|
|
||||||
|
*objtype = TRUSTEE_BINDERY_GROUP;
|
||||||
|
object_id = ncp_17_35(namebuf, TRUSTEE_BINDERY_GROUP);
|
||||||
|
return(object_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int trustee_path_is_dir(char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (!path || !*path || trustee_same(path, ".") || trustee_same(path, ".\\") ||
|
||||||
|
trustee_same(path, "./"))
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
if (stat(path, &st) == 0) {
|
||||||
|
if (st.st_mode & S_IFDIR)
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
40
trustee.h
Normal file
40
trustee.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef TRUSTEE_H
|
||||||
|
#define TRUSTEE_H
|
||||||
|
|
||||||
|
#define TRUSTEE_BINDERY_USER 0x0001
|
||||||
|
#define TRUSTEE_BINDERY_GROUP 0x0002
|
||||||
|
|
||||||
|
#define TRUSTEE_RIGHT_READ 0x0001
|
||||||
|
#define TRUSTEE_RIGHT_WRITE 0x0002
|
||||||
|
#define TRUSTEE_RIGHT_OPEN 0x0004
|
||||||
|
#define TRUSTEE_RIGHT_CREATE 0x0008
|
||||||
|
#define TRUSTEE_RIGHT_DELETE 0x0010
|
||||||
|
#define TRUSTEE_RIGHT_OWNER 0x0020
|
||||||
|
#define TRUSTEE_RIGHT_SEARCH 0x0040
|
||||||
|
#define TRUSTEE_RIGHT_MODIFY 0x0080
|
||||||
|
#define TRUSTEE_RIGHT_SUPER 0x0100
|
||||||
|
|
||||||
|
#define TRUSTEE_RIGHT_ALL_386 (TRUSTEE_RIGHT_SUPER | TRUSTEE_RIGHT_READ | \
|
||||||
|
TRUSTEE_RIGHT_WRITE | TRUSTEE_RIGHT_CREATE | \
|
||||||
|
TRUSTEE_RIGHT_DELETE | TRUSTEE_RIGHT_MODIFY | \
|
||||||
|
TRUSTEE_RIGHT_SEARCH | TRUSTEE_RIGHT_OWNER)
|
||||||
|
|
||||||
|
int trustee_same(char *a, char *b);
|
||||||
|
int trustee_is_help(char *s);
|
||||||
|
int trustee_is_option(char *s);
|
||||||
|
int trustee_is_subdirs_option(char *s);
|
||||||
|
int trustee_is_files_option(char *s);
|
||||||
|
int trustee_current_dhandle(uint8 *connid, uint8 *dhandle);
|
||||||
|
void trustee_upcopy(char *dst, char *src, int max);
|
||||||
|
void trustee_basename(char *dst, char *src, int max);
|
||||||
|
void trustee_header_path(char *out, char *path, int max);
|
||||||
|
void trustee_join_path(char *out, char *base, char *name, int max);
|
||||||
|
int trustee_is_dot_dir(char *name);
|
||||||
|
int trustee_parse_right_word(char *s, uint16 *rights);
|
||||||
|
void trustee_rights_bracket(uint16 rights, char *out);
|
||||||
|
uint32 trustee_lookup_object(char *name, uint16 *objtype, int objtype_given);
|
||||||
|
int trustee_path_is_dir(char *path);
|
||||||
|
int trustee_path_has_wildcards(char *path);
|
||||||
|
void trustee_parent_pattern(char *dir, char *pattern, char *path, int maxdir, int maxpat);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user