diff --git a/README.md b/README.md index 0b37425..1085da6 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,25 @@ DOS client-side utilities for **mars_nwe** and compatible NetWare-style NCP envi 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 [args...]`, or -- a renamed executable such as `login.exe`, `map.exe`, `flag.exe`, `flagdir.exe`, `capture.exe`, or `logout.exe`. +- 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 tools. +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: @@ -26,7 +31,7 @@ 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 `RIGHTS`, `GRANT`, `REVOKE`, `NDIR`, `PURGE`, and `SALVAGE` +- Additional Novell-like utilities such as `NDIR`, `PURGE`, and `SALVAGE` ## Features @@ -41,6 +46,9 @@ Still to validate or continue: - 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` @@ -65,6 +73,9 @@ The current command dispatcher includes these built-ins: - `FLAG` - `FLAGDIR` - `RIGHTS` +- `GRANT` +- `REVOKE` +- `REMOVE` - `DEBUG` - `ECHO` - `CD` @@ -117,8 +128,11 @@ 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 operations. +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 @@ -377,10 +391,10 @@ Typical usage: RIGHTS [path] ``` -Supported in this first version: +Supported: - directory paths -- file paths, using the parent directory rights for the first read-only implementation +- file paths - Novell-like display of the effective rights mask Rights are shown in the traditional order: @@ -390,6 +404,94 @@ 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. @@ -504,6 +606,10 @@ The install rules deploy the same binary multiple times into `SYS/public`, inclu - `slist.exe` - `flag.exe` - `flagdir.exe` +- `rights.exe` +- `grant.exe` +- `revoke.exe` +- `remove.exe` - `capture.exe` - `endcap.exe` @@ -514,7 +620,9 @@ They also install selected copies such as `login.exe`, `map.exe`, and `slist.exe - `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. -- The verified Client32 path uses NCP 87 subfunction 6 for obtaining DOS information and subfunction 7 for modifying DOS information. +- `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. @@ -523,7 +631,7 @@ They also install selected copies such as `login.exe`, `map.exe`, and `slist.exe 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 tools, but not yet generalized to every command. +- 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. diff --git a/flag.c b/flag.c index 36dba7a..7e697ac 100644 --- a/flag.c +++ b/flag.c @@ -54,32 +54,6 @@ static uint32 flag_get_dword_lh(uint8 *p) ((uint32)p[3] << 24)); } -static int flag_get_current_drive(void) -{ - REGS regs; - - regs.h.ah = 0x19; /* DOS get current default drive */ - int86(0x21, ®s, ®s); /* AL = 0 for A:, 1 for B:, ... */ - - return((int)regs.h.al); -} - -static int flag_current_dhandle(uint8 *dhandle) -{ - uint8 connid = 0; - uint8 flags = 0; - int drive; - - drive = flag_get_current_drive(); - if (get_drive_info((uint8)drive, &connid, dhandle, &flags)) - return(-1); - - if (!connid || (flags & 0x80)) - return(-1); - - return(0); -} - static int flag_add_handle_path(uint8 *p, uint8 dhandle, char *name) { int nlen; @@ -115,11 +89,12 @@ static int flag_ncp87_obtain_attrs(char *name, uint32 *attrs) uint16 len; uint8 data[128]; } repl; + uint8 connid = 0; uint8 dhandle = 0; uint8 *p; int hlen; - if (flag_current_dhandle(&dhandle)) + if (tool_current_dhandle(&connid, &dhandle)) return(-1); /* @@ -169,11 +144,12 @@ static int flag_ncp87_modify_attrs(char *name, uint32 attrs) uint16 len; uint8 data[8]; } repl; + uint8 connid = 0; uint8 dhandle = 0; uint8 *p; int hlen; - if (flag_current_dhandle(&dhandle)) + if (tool_current_dhandle(&connid, &dhandle)) return(-1); /* @@ -241,18 +217,6 @@ static int flag_ncp87_modify_attrs(char *name, uint32 attrs) #define _A_ARCH 0x20 #endif -static int flag_same(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 void flag_help(void) { fprintf(stdout, "USAGE: FLAG [path [ option | [+|-] attribute(s) ] [SUB]]\n"); @@ -294,52 +258,52 @@ static int flag_attr_mask(char *s, uint32 *setbits, uint32 *clearbits) if (!*p) return(-1); - if (flag_same(p, "RO")) { + if (tool_strsame(p, "RO")) { if (set) { *setbits |= (NWFA_RO | NWFA_DI | NWFA_RI); } else { *clearbits |= (NWFA_RO | NWFA_DI | NWFA_RI); } - } else if (flag_same(p, "RW")) { + } else if (tool_strsame(p, "RW")) { *clearbits |= (NWFA_RO | NWFA_DI | NWFA_RI); - } else if (flag_same(p, "S")) { + } else if (tool_strsame(p, "S")) { if (set) *setbits |= NWFA_S; else *clearbits |= NWFA_S; - } else if (flag_same(p, "H")) { + } else if (tool_strsame(p, "H")) { if (set) *setbits |= NWFA_H; else *clearbits |= NWFA_H; - } else if (flag_same(p, "SY") || flag_same(p, "SYS") || flag_same(p, "SYSTEM")) { + } 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 (flag_same(p, "T")) { + } else if (tool_strsame(p, "T")) { if (set) *setbits |= NWFA_T; else *clearbits |= NWFA_T; - } else if (flag_same(p, "P")) { + } else if (tool_strsame(p, "P")) { if (set) *setbits |= NWFA_P; else *clearbits |= NWFA_P; - } else if (flag_same(p, "A")) { + } else if (tool_strsame(p, "A")) { if (set) *setbits |= NWFA_A; else *clearbits |= NWFA_A; - } else if (flag_same(p, "RA")) { + } else if (tool_strsame(p, "RA")) { if (set) *setbits |= NWFA_RA; else *clearbits |= NWFA_RA; - } else if (flag_same(p, "WA")) { + } else if (tool_strsame(p, "WA")) { if (set) *setbits |= NWFA_WA; else *clearbits |= NWFA_WA; - } else if (flag_same(p, "CI")) { + } else if (tool_strsame(p, "CI")) { if (set) *setbits |= NWFA_CI; else *clearbits |= NWFA_CI; - } else if (flag_same(p, "DI")) { + } else if (tool_strsame(p, "DI")) { if (set) *setbits |= NWFA_DI; else *clearbits |= NWFA_DI; - } else if (flag_same(p, "RI")) { + } else if (tool_strsame(p, "RI")) { if (set) *setbits |= NWFA_RI; else *clearbits |= NWFA_RI; - } else if (flag_same(p, "N") || flag_same(p, "NORMAL")) { + } 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 (flag_same(p, "ALL")) { + } 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); @@ -389,15 +353,6 @@ static void flag_display_one_paged(char *name, uint32 attr, } -static int flag_has_wildcards(char *s) -{ - while (*s) { - if (*s == '*' || *s == '?') return(1); - s++; - } - return(0); -} - static int flag_list(char *pattern) { struct find_t ff; @@ -479,19 +434,19 @@ int func_flag(int argc, char *argv[], int mode) (void)mode; - if (argc > 1 && (flag_same(argv[1], "/?") || flag_same(argv[1], "-?") || - flag_same(argv[1], "?"))) { + 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 (flag_same(path, "SUB")) path = "*.*"; + if (tool_strsame(path, "SUB")) path = "*.*"; } for (i = 2; i < argc; i++) { - if (flag_same(argv[i], "SUB")) continue; + if (tool_strsame(argv[i], "SUB")) continue; rc = flag_attr_mask(argv[i], &setbits, &clearbits); if (rc < 0) return(1); diff --git a/flagdir.c b/flagdir.c index 79c40fc..2e5436f 100644 --- a/flagdir.c +++ b/flagdir.c @@ -28,110 +28,6 @@ #define _A_ARCH 0x20 #endif -static int fd_same(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 void fd_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; -} - -static int fd_get_current_drive(void) -{ - REGS regs; - regs.h.ah = 0x19; - int86(0x21, ®s, ®s); - return((int)regs.h.al); -} - -static int fd_current_dhandle(uint8 *dhandle) -{ - uint8 connid = 0; - uint8 flags = 0; - int drive; - - drive = fd_get_current_drive(); - if (get_drive_info((uint8)drive, &connid, dhandle, &flags)) - return(-1); - - if (!connid || (flags & 0x80)) - return(-1); - - return(0); -} - -static int fd_current_prefix(char *out, int max) -{ - uint8 connid = 0; - uint8 dhandle = 0; - uint8 flags = 0; - int drive; - char server[52]; - char path[260]; - char volume[32]; - char *p; - int i = 0; - - if (!out || max < 8) - return(-1); - - out[0] = '\0'; - - drive = fd_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'; - - path[0] = '\0'; - if (get_dir_path(dhandle, path) || !path[0]) - return(-1); - - p = strchr(path, ':'); - if (!p) - return(-1); - - while (path + i < p && i < (int)sizeof(volume) - 1) { - volume[i] = path[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); -} - static int fd_current_display_path(uint8 dhandle, char *out, int max) { char path[260]; @@ -160,98 +56,6 @@ static int fd_current_display_path(uint8 dhandle, char *out, int max) return(0); } -static int fd_is_current_path(char *path) -{ - if (!path || !*path) return(1); - if (fd_same(path, ".")) return(1); - if (fd_same(path, ".\\")) return(1); - if (fd_same(path, "./")) return(1); - return(0); -} - -static int fd_has_wildcards(char *s) -{ - if (!s) return(0); - while (*s) { - if (*s == '*' || *s == '?') - return(1); - s++; - } - return(0); -} - -static void fd_split_pattern(char *spec, char *dir, char *pat) -{ - char tmp[260]; - char *p; - - if (!spec || !*spec) { - strcpy(dir, "."); - strcpy(pat, "*.*"); - return; - } - - strmaxcpy(tmp, spec, sizeof(tmp) - 1); - p = strrchr(tmp, '\\'); - if (!p) p = strrchr(tmp, '/'); - - if (p) { - *p++ = '\0'; - if (tmp[0]) - strmaxcpy(dir, tmp, 259); - else - strcpy(dir, "."); - strmaxcpy(pat, p, 259); - } else { - strcpy(dir, "."); - strmaxcpy(pat, tmp, 259); - } - - if (!pat[0]) - strcpy(pat, "*.*"); -} - -static void fd_join_path(char *out, char *dir, char *name, int max) -{ - int len; - - out[0] = '\0'; - - if (!dir || !dir[0] || fd_same(dir, ".")) { - strmaxcpy(out, name, max - 1); - return; - } - - strmaxcpy(out, dir, 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); -} - -static void fd_basename(char *out, char *path, int max) -{ - char up[260]; - char *p; - - fd_upcopy(up, path, sizeof(up)); - p = strrchr(up, '\\'); - if (!p) p = strrchr(up, ':'); - - if (p) - strmaxcpy(out, p + 1, max - 1); - else - strmaxcpy(out, up, max - 1); -} - static void fd_help(void) { fprintf(stdout, "386 Usage: Flagdir [path [option...]]\n"); @@ -265,20 +69,20 @@ static void fd_help(void) static int fd_attr_mask(char *s, uint32 *setbits, uint32 *clearbits) { - if (fd_same(s, "N") || fd_same(s, "NORMAL")) { + if (tool_strsame(s, "N") || tool_strsame(s, "NORMAL")) { *clearbits |= FD_DIR_BITS; - } else if (fd_same(s, "S") || fd_same(s, "SY") || - fd_same(s, "SYS") || fd_same(s, "SYSTEM")) { + } else if (tool_strsame(s, "S") || tool_strsame(s, "SY") || + tool_strsame(s, "SYS") || tool_strsame(s, "SYSTEM")) { *setbits |= FD_NWFA_SY; - } else if (fd_same(s, "H") || fd_same(s, "HIDDEN")) { + } else if (tool_strsame(s, "H") || tool_strsame(s, "HIDDEN")) { *setbits |= FD_NWFA_H; - } else if (fd_same(s, "DI") || fd_same(s, "DELETEINHIBIT")) { + } else if (tool_strsame(s, "DI") || tool_strsame(s, "DELETEINHIBIT")) { *setbits |= FD_NWFA_DI; - } else if (fd_same(s, "P") || fd_same(s, "PURGE")) { + } else if (tool_strsame(s, "P") || tool_strsame(s, "PURGE")) { *setbits |= FD_NWFA_P; - } else if (fd_same(s, "RI") || fd_same(s, "RENAMEINHIBIT")) { + } else if (tool_strsame(s, "RI") || tool_strsame(s, "RENAMEINHIBIT")) { *setbits |= FD_NWFA_RI; - } else if (fd_same(s, "PRIVATE") || fd_same(s, "PR")) { + } 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 { @@ -326,9 +130,9 @@ static void fd_display_header(char *path) char up[260]; char prefix[90]; - fd_upcopy(up, path, sizeof(up)); + tool_upcopy(up, path, sizeof(up)); - if (fd_current_prefix(prefix, sizeof(prefix))) + if (tool_current_prefix(prefix, sizeof(prefix))) prefix[0] = '\0'; fprintf(stdout, "%s%s \n", prefix, up); @@ -338,7 +142,7 @@ static void fd_display_row(char *name, uint32 attrs) { char base[260]; - fd_basename(base, name, sizeof(base)); + tool_basename(base, name, sizeof(base)); fprintf(stdout, " %-12.12s ", base); fd_print_attrs(attrs); } @@ -354,7 +158,7 @@ static int fd_is_directory(char *path) struct find_t ff; unsigned attr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR | _A_ARCH; - if (fd_is_current_path(path)) + if (tool_is_current_path(path)) return(1); if (_dos_findfirst(path, attr, &ff)) @@ -392,10 +196,10 @@ static int fd_process_one(char *path, char *display_path, uint8 dhandle, return(1); } - ncp_path = fd_is_current_path(path) ? "" : path; + ncp_path = tool_is_current_path(path) ? "" : path; if (fd_obtain(ncp_path, dhandle, &attrs)) { - if (fd_is_current_path(path) && display_path && !display_path[0] && + if (tool_is_current_path(path) && display_path && !display_path[0] && !have_change) { attrs = 0; } else { @@ -439,8 +243,8 @@ static int fd_process_wild(char *spec, uint8 dhandle, int continuous = 0; unsigned attr = _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR | _A_ARCH; - fd_split_pattern(spec, dir, pat); - fd_join_path(search, dir, pat, sizeof(search)); + 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); @@ -452,7 +256,7 @@ static int fd_process_wild(char *spec, uint8 dhandle, do { if ((ff.attrib & _A_SUBDIR) && strcmp(ff.name, ".") && strcmp(ff.name, "..")) { - fd_join_path(full, dir, ff.name, sizeof(full)); + tool_join_path(full, dir, ff.name, sizeof(full)); if (fd_process_one(full, ff.name, dhandle, setbits, clearbits, have_change, 0)) rc = 1; @@ -473,6 +277,7 @@ 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; @@ -481,8 +286,8 @@ int func_flagdir(int argc, char *argv[], int mode) (void)mode; - if (argc > 1 && (fd_same(argv[1], "/?") || fd_same(argv[1], "-?") || - fd_same(argv[1], "?"))) { + if (argc > 1 && (tool_strsame(argv[1], "/?") || tool_strsame(argv[1], "-?") || + tool_strsame(argv[1], "?"))) { fd_help(); return(0); } @@ -490,7 +295,7 @@ int func_flagdir(int argc, char *argv[], int mode) if (argc > 1) path = argv[1]; - if (fd_current_dhandle(&dhandle)) { + if (tool_current_dhandle(&connid, &dhandle)) { fprintf(stderr, "FlagDir only works on network directories.\n"); return(1); } @@ -501,10 +306,10 @@ int func_flagdir(int argc, char *argv[], int mode) have_change = 1; } - if (fd_has_wildcards(path)) + if (tool_has_wildcards(path)) return(fd_process_wild(path, dhandle, setbits, clearbits, have_change)); - if (fd_is_current_path(path)) { + if (tool_is_current_path(path)) { if (fd_current_display_path(dhandle, display_path, sizeof(display_path))) strcpy(display_path, "."); } else { diff --git a/grant.c b/grant.c index b8830c5..c5ddbc1 100644 --- a/grant.c +++ b/grant.c @@ -22,24 +22,6 @@ NCP_RIGHT_MODIFY | NCP_RIGHT_SEARCH | \ NCP_RIGHT_OWNER) -static int grant_same(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 grant_is_help(char *s) -{ - if (!s) return(0); - return(grant_same(s, "/?") || grant_same(s, "-?") || grant_same(s, "?")); -} - static void grant_usage_error(void) { fprintf(stdout, "Command line arguments violate grammar defined for GRANT.\n\n"); @@ -63,128 +45,6 @@ static void grant_usage(void) fprintf(stdout, "A = Access Control\n"); } -static int grant_get_current_drive(void) -{ - REGS regs; - - regs.h.ah = 0x19; - int86(0x21, ®s, ®s); - return((int)regs.h.al); -} - -static int grant_current_dhandle(uint8 *connid, uint8 *dhandle) -{ - uint8 flags = 0; - int drive = grant_get_current_drive(); - - if (get_drive_info((uint8)drive, connid, dhandle, &flags)) - return(-1); - - if (!*connid || (flags & 0x80)) - return(-1); - - return(0); -} - - -static int grant_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 = grant_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); -} - -static void grant_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; -} - -static void grant_basename(char *dst, char *src, int max) -{ - char up[260]; - char *p; - - grant_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); -} - -static void grant_header_path(char *out, char *path, int max) -{ - char prefix[90]; - char up[260]; - - if (grant_current_prefix(prefix, sizeof(prefix))) - prefix[0] = '\0'; - - grant_upcopy(up, path, sizeof(up)); - - strmaxcpy(out, prefix, max - 1); - if ((int)(strlen(out) + strlen(up)) < max - 1) - strcat(out, up); -} - static void grant_rights_bracket(uint16 rights, char *out) { out[0] = (rights & NCP_RIGHT_SUPER) ? 'S' : ' '; @@ -226,54 +86,54 @@ static void grant_rights_string(uint16 rights, char *out) static int grant_add_right_word(char *s, uint16 *rights) { - if (grant_same(s, "ALL")) { + if (tool_strsame(s, "ALL")) { *rights = NCP_RIGHT_ALL_386; return(0); } - if (grant_same(s, "N") || grant_same(s, "NONE")) { + if (tool_strsame(s, "N") || tool_strsame(s, "NONE")) { *rights = 0; return(0); } - if (grant_same(s, "S") || grant_same(s, "SUPERVISOR")) { + if (tool_strsame(s, "S") || tool_strsame(s, "SUPERVISOR")) { *rights |= NCP_RIGHT_SUPER; return(0); } - if (grant_same(s, "R") || grant_same(s, "READ")) { + if (tool_strsame(s, "R") || tool_strsame(s, "READ")) { *rights |= NCP_RIGHT_READ; return(0); } - if (grant_same(s, "W") || grant_same(s, "WRITE")) { + if (tool_strsame(s, "W") || tool_strsame(s, "WRITE")) { *rights |= NCP_RIGHT_WRITE; return(0); } - if (grant_same(s, "C") || grant_same(s, "CREATE")) { + if (tool_strsame(s, "C") || tool_strsame(s, "CREATE")) { *rights |= NCP_RIGHT_CREATE; return(0); } - if (grant_same(s, "E") || grant_same(s, "ERASE")) { + if (tool_strsame(s, "E") || tool_strsame(s, "ERASE")) { *rights |= NCP_RIGHT_DELETE; return(0); } - if (grant_same(s, "M") || grant_same(s, "MODIFY")) { + if (tool_strsame(s, "M") || tool_strsame(s, "MODIFY")) { *rights |= NCP_RIGHT_MODIFY; return(0); } - if (grant_same(s, "F") || grant_same(s, "FILESCAN") || - grant_same(s, "FILE") || grant_same(s, "SCAN")) { + if (tool_strsame(s, "F") || tool_strsame(s, "FILESCAN") || + tool_strsame(s, "FILE") || tool_strsame(s, "SCAN")) { *rights |= NCP_RIGHT_SEARCH; return(0); } - if (grant_same(s, "A") || grant_same(s, "ACCESS") || - grant_same(s, "CONTROL") || grant_same(s, "ACCESSCONTROL")) { + if (tool_strsame(s, "A") || tool_strsame(s, "ACCESS") || + tool_strsame(s, "CONTROL") || tool_strsame(s, "ACCESSCONTROL")) { *rights |= NCP_RIGHT_OWNER; return(0); } @@ -281,13 +141,6 @@ static int grant_add_right_word(char *s, uint16 *rights) return(-1); } -static int grant_is_option(char *s) -{ - if (!s) return(0); - return(s[0] == '/' || s[0] == '-'); -} - - static int grant_last_rc = 0; static int grant_set_one(char *path, uint16 dhandle, @@ -305,34 +158,6 @@ static int grant_set_one(char *path, uint16 dhandle, return(rc); } -static int grant_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); -} - -static void grant_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); -} - /* * Apply the grant to PATH and every directory below it. * @@ -351,12 +176,12 @@ static int grant_set_subdirs(char *path, uint16 dhandle, if (grant_set_one(path, dhandle, object_id, rights)) rc = 1; - grant_join_path(pattern, path, "*.*", sizeof(pattern)); + tool_join_path(pattern, path, "*.*", sizeof(pattern)); if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) { do { - if ((ff.attrib & _A_SUBDIR) && !grant_is_dot_dir(ff.name)) { - grant_join_path(child, path, ff.name, sizeof(child)); + 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; } @@ -384,7 +209,7 @@ int func_grant(int argc, char *argv[], int mode) (void)mode; - if (argc < 2 || grant_is_help(argv[1])) { + if (argc < 2 || tool_is_help_arg(argv[1])) { if (argc < 2) grant_usage_error(); grant_usage(); @@ -395,10 +220,10 @@ int func_grant(int argc, char *argv[], int mode) * GRANT rightslist* [FOR path] TO [USER|GROUP] name [options] */ while (i < argc) { - if (grant_same(argv[i], "FOR") || grant_same(argv[i], "TO")) + if (tool_strsame(argv[i], "FOR") || tool_strsame(argv[i], "TO")) break; - if (grant_is_option(argv[i])) + if (tool_is_option(argv[i])) break; if (grant_add_right_word(argv[i], &rights)) { @@ -416,7 +241,7 @@ int func_grant(int argc, char *argv[], int mode) return(1); } - if (grant_same(argv[i], "FOR")) { + if (tool_strsame(argv[i], "FOR")) { i++; if (i >= argc) { grant_usage_error(); @@ -426,17 +251,17 @@ int func_grant(int argc, char *argv[], int mode) path = argv[i++]; } - if (i >= argc || !grant_same(argv[i], "TO")) { + if (i >= argc || !tool_strsame(argv[i], "TO")) { grant_usage_error(); grant_usage(); return(1); } i++; - if (i < argc && grant_same(argv[i], "USER")) { + if (i < argc && tool_strsame(argv[i], "USER")) { objtype = GRANT_BINDERY_USER; i++; - } else if (i < argc && grant_same(argv[i], "GROUP")) { + } else if (i < argc && tool_strsame(argv[i], "GROUP")) { objtype = GRANT_BINDERY_GROUP; i++; } @@ -450,7 +275,7 @@ int func_grant(int argc, char *argv[], int mode) objname = argv[i++]; while (i < argc) { - if (!grant_is_option(argv[i])) { + if (!tool_is_option(argv[i])) { grant_usage_error(); grant_usage(); return(1); @@ -461,15 +286,15 @@ int func_grant(int argc, char *argv[], int mode) * NCP87 trustee-add call. /SUBDIRECTORIES recursively applies the * same grant to all subdirectories below the given path. */ - if (grant_same(argv[i], "/FILES") || grant_same(argv[i], "-FILES") || - grant_same(argv[i], "/F") || grant_same(argv[i], "-F")) { + if (tool_strsame(argv[i], "/FILES") || tool_strsame(argv[i], "-FILES") || + tool_strsame(argv[i], "/F") || tool_strsame(argv[i], "-F")) { i++; continue; } - if (grant_same(argv[i], "/SUBDIRECTORIES") || - grant_same(argv[i], "-SUBDIRECTORIES") || - grant_same(argv[i], "/S") || grant_same(argv[i], "-S")) { + 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; @@ -480,7 +305,7 @@ int func_grant(int argc, char *argv[], int mode) return(1); } - if (grant_current_dhandle(&connid, &dhandle)) { + if (tool_current_dhandle(&connid, &dhandle)) { fprintf(stdout, "Specified path not locatable.\n"); return(1); } @@ -508,8 +333,8 @@ int func_grant(int argc, char *argv[], int mode) char base[80]; char bracket[10]; - grant_header_path(header, path, sizeof(header)); - grant_basename(base, path, sizeof(base)); + tool_header_path(header, path, sizeof(header)); + tool_basename(base, path, sizeof(base)); grant_rights_bracket(rights, bracket); fprintf(stdout, "%s\n", header); diff --git a/net.exe b/net.exe index 431c3ab..e7db07f 100755 Binary files a/net.exe and b/net.exe differ diff --git a/net.h b/net.h index 9d4265c..d90038a 100644 --- a/net.h +++ b/net.h @@ -146,6 +146,26 @@ 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); diff --git a/rights.c b/rights.c index d329aee..09ec53c 100644 --- a/rights.c +++ b/rights.c @@ -33,24 +33,6 @@ static uint8 rights_map_ncp_mask(uint16 ncp_rights); -static int rights_same(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 rights_is_help(char *s) -{ - if (!s) return(0); - return(rights_same(s, "/?") || rights_same(s, "-?") || rights_same(s, "?")); -} - static void rights_usage(void) { fprintf(stdout, "Usage: RIGHTS [path]\n\n"); @@ -58,59 +40,12 @@ static void rights_usage(void) fprintf(stdout, " Modify | File scan | Access Control\n"); } -static int rights_get_current_drive(void) -{ - REGS regs; - - regs.h.ah = 0x19; - int86(0x21, ®s, ®s); - return((int)regs.h.al); -} - -static int rights_current_dhandle(uint8 *connid, uint8 *dhandle) -{ - uint8 flags = 0; - int drive = rights_get_current_drive(); - - if (get_drive_info((uint8)drive, connid, dhandle, &flags)) - return(-1); - - if (!*connid || (flags & 0x80)) - return(-1); - - return(0); -} - -static int rights_is_current_path(char *path) -{ - if (!path || !*path) return(1); - if (rights_same(path, ".")) return(1); - if (rights_same(path, ".\\")) return(1); - if (rights_same(path, "./")) return(1); - return(0); -} - -static void rights_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; -} - static void rights_parent_path(char *dst, char *src, int max) { char tmp[260]; char *p; - rights_upcopy(tmp, src, sizeof(tmp)); + tool_upcopy(tmp, src, sizeof(tmp)); p = strrchr(tmp, '\\'); if (!p) p = strrchr(tmp, ':'); @@ -134,7 +69,7 @@ static int rights_path_is_dir(char *path) { struct stat st; - if (rights_is_current_path(path)) + if (tool_is_current_path(path)) return(1); if (stat(path, &st) == 0) { @@ -146,78 +81,6 @@ static int rights_path_is_dir(char *path) } -static int rights_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 = rights_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); -} - - -static void rights_make_header_path(char *out, char *path) -{ - char up[260]; - char prefix[90]; - - if (rights_current_prefix(prefix, sizeof(prefix))) - prefix[0] = '\0'; - - if (rights_is_current_path(path)) { - strcpy(out, prefix); - return; - } - - rights_upcopy(up, path, sizeof(up)); - strcpy(out, prefix); - strcat(out, up); -} - static int rights_effective_mask(char *path, int is_dir, uint8 *mask) { uint8 connid = 0; @@ -229,7 +92,7 @@ static int rights_effective_mask(char *path, int is_dir, uint8 *mask) if (mask) *mask = 0; - if (rights_current_dhandle(&connid, &dhandle)) + if (tool_current_dhandle(&connid, &dhandle)) return(-1); /* @@ -238,7 +101,7 @@ static int rights_effective_mask(char *path, int is_dir, uint8 *mask) * 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(rights_is_current_path(path) ? "" : path, + if (!c32_ncp87_get_effective_rights(tool_is_current_path(path) ? "" : path, (uint16)dhandle, &ncp_rights, NULL, NULL, NULL)) { @@ -251,10 +114,10 @@ static int rights_effective_mask(char *path, int is_dir, uint8 *mask) * handle and use the returned old-style effective-rights byte. * This cannot directly target a file, so files are mapped to their parent. */ - if (rights_is_current_path(path)) { + if (tool_is_current_path(path)) { usepath[0] = '\0'; } else if (is_dir) { - rights_upcopy(usepath, path, sizeof(usepath)); + tool_upcopy(usepath, path, sizeof(usepath)); } else { rights_parent_path(usepath, path, sizeof(usepath)); } @@ -333,7 +196,7 @@ static void rights_display(char *path, int is_dir, uint8 mask) char hdr[300]; char mstr[10]; - rights_make_header_path(hdr, path); + tool_header_path(hdr, path, sizeof(hdr)); rights_mask_string(mask, mstr); fprintf(stdout, "%s\n", hdr); @@ -389,7 +252,7 @@ int func_rights(int argc, char *argv[], int mode) } if (argc == 2) { - if (rights_is_help(argv[1])) { + if (tool_is_help_arg(argv[1])) { rights_usage(); return(0); } diff --git a/tools.c b/tools.c index d3bf7cf..427edd4 100644 --- a/tools.c +++ b/tools.c @@ -366,3 +366,259 @@ int tool_page_line(int *line_count, int *continuous) 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); +} diff --git a/trustee.c b/trustee.c index 2adc2cd..44b1ace 100644 --- a/trustee.c +++ b/trustee.c @@ -9,28 +9,34 @@ #define S_IFDIR 0040000 #endif -int trustee_same(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); -} -int trustee_is_help(char *s) -{ - if (!s) return(0); - return(trustee_same(s, "/?") || trustee_same(s, "-?") || trustee_same(s, "?")); -} -int trustee_is_option(char *s) +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) { - if (!s) return(0); - return(s[0] == '/' || s[0] == '-'); + 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) @@ -48,155 +54,6 @@ int trustee_is_files_option(char *s) trustee_same(s, "/F") || trustee_same(s, "-F")); } -static int trustee_get_current_drive(void) -{ - REGS regs; - - regs.h.ah = 0x19; - int86(0x21, ®s, ®s); - return((int)regs.h.al); -} - -int trustee_current_dhandle(uint8 *connid, uint8 *dhandle) -{ - uint8 flags = 0; - int drive = trustee_get_current_drive(); - - if (get_drive_info((uint8)drive, connid, dhandle, &flags)) - return(-1); - - if (!*connid || (flags & 0x80)) - return(-1); - - return(0); -} - -static int trustee_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 = trustee_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); -} - -void trustee_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 trustee_basename(char *dst, char *src, int max) -{ - char up[260]; - char *p; - - trustee_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 trustee_header_path(char *out, char *path, int max) -{ - char prefix[90]; - char up[260]; - - if (trustee_current_prefix(prefix, sizeof(prefix))) - prefix[0] = '\0'; - - trustee_upcopy(up, path, sizeof(up)); - - strmaxcpy(out, prefix, max - 1); - if ((int)(strlen(out) + strlen(up)) < max - 1) - strcat(out, up); -} - -void trustee_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 trustee_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); -} - int trustee_parse_right_word(char *s, uint16 *rights) { if (trustee_same(s, "ALL")) { @@ -306,36 +163,3 @@ int trustee_path_is_dir(char *path) return(0); } -int trustee_path_has_wildcards(char *path) -{ - if (!path) return(0); - while (*path) { - if (*path == '*' || *path == '?') return(1); - path++; - } - return(0); -} - -void trustee_parent_pattern(char *dir, char *pattern, char *path, int maxdir, int maxpat) -{ - char tmp[260]; - char *p; - - trustee_upcopy(tmp, path, sizeof(tmp)); - p = strrchr(tmp, '\\'); - if (!p) p = strrchr(tmp, ':'); - - if (p) { - char save = *p; - *p = '\0'; - strmaxcpy(pattern, p + 1, maxpat - 1); - if (save == ':') { - *p = ':'; - *(p + 1) = '\0'; - } - strmaxcpy(dir, tmp, maxdir - 1); - } else { - strmaxcpy(dir, ".", maxdir - 1); - strmaxcpy(pattern, tmp, maxpat - 1); - } -}