dosutils: factor shared helpers and update README
Move common DOS utility helper code into tools.c and expose it through net.h. This removes duplicated command-local helpers from GRANT, RIGHTS, FLAG, FLAGDIR and the trustee helper layer. The shared helpers cover case-insensitive argument comparison, help and option detection, /FILES and /SUBDIRS parsing, current network directory handle lookup, current volume prefix formatting, uppercase DOS path copying, basename/header-path handling, wildcard detection and simple path joining/splitting. Keep the command frontends smaller and less coupled so the current multicall utility can later be split into smaller grouped multicall binaries, such as trustee tools, login/session tools and file/flag tools. Update the DOS utilities README for the newer Client32 and trustee commands. Document RIGHTS, GRANT, REVOKE and REMOVE in the status, feature, command and install sections. Add command reference entries for the trustee tools, including Novell-style syntax, supported rights, recursive/file options and missing-trustee behavior. Also mention the shared trustee helper layer and common tools.c helpers used by the newer command frontends.
This commit is contained in:
241
flagdir.c
241
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 {
|
||||
|
||||
Reference in New Issue
Block a user