flag
This commit is contained in:
290
flag.c
290
flag.c
@@ -3,6 +3,176 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NetWare old file-info attributes.
|
||||||
|
* NCP 23/15 returns FileAttributes byte and ExtendedFileAttributes byte.
|
||||||
|
* NCP 23/16 writes them back while preserving the rest of the scanned info.
|
||||||
|
*
|
||||||
|
* This gives us real NetWare flags for:
|
||||||
|
* S Shareable byte0 bit7
|
||||||
|
* T Transactional byte1 bit4
|
||||||
|
* RA Read Audit byte1 bit6
|
||||||
|
* WA Write Audit byte1 bit7
|
||||||
|
*
|
||||||
|
* Full 386 byte2 flags P/CI/DI/RI need NCP 87/35 later.
|
||||||
|
*/
|
||||||
|
#define NWFA_RO 0x0001UL
|
||||||
|
#define NWFA_H 0x0002UL
|
||||||
|
#define NWFA_SY 0x0004UL
|
||||||
|
#define NWFA_A 0x0020UL
|
||||||
|
#define NWFA_S 0x0080UL
|
||||||
|
#define NWFA_T 0x1000UL
|
||||||
|
#define NWFA_RA 0x4000UL
|
||||||
|
#define NWFA_WA 0x8000UL
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16 next_index;
|
||||||
|
char name[15];
|
||||||
|
uint8 attr;
|
||||||
|
uint8 extattr;
|
||||||
|
uint8 raw[76]; /* file size + dates + owner + archive + reserved */
|
||||||
|
} FLAG_NWINFO;
|
||||||
|
|
||||||
|
static int flag_current_dhandle(uint8 *dhandle)
|
||||||
|
{
|
||||||
|
uint8 connid = 0;
|
||||||
|
uint8 flags = 0;
|
||||||
|
int drive;
|
||||||
|
|
||||||
|
drive = getdisk(); /* 0=A */
|
||||||
|
if (get_drive_info((uint8)drive, &connid, dhandle, &flags))
|
||||||
|
return(-1);
|
||||||
|
if (!connid || (flags & 0x80))
|
||||||
|
return(-1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_ncp23_scan(uint8 dhandle, char *name, FLAG_NWINFO *info)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 func;
|
||||||
|
uint8 last[2];
|
||||||
|
uint8 dhandle;
|
||||||
|
uint8 searchattr;
|
||||||
|
uint8 namelen;
|
||||||
|
uint8 name[255];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 next[2];
|
||||||
|
uint8 fname[14];
|
||||||
|
uint8 attr;
|
||||||
|
uint8 extattr;
|
||||||
|
uint8 raw[76];
|
||||||
|
} repl;
|
||||||
|
int nlen;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
nlen = min(255, strlen(name));
|
||||||
|
req.func = 0x0f;
|
||||||
|
req.last[0] = 0xff;
|
||||||
|
req.last[1] = 0xff;
|
||||||
|
req.dhandle = dhandle;
|
||||||
|
req.searchattr = 0x06; /* include hidden/system */
|
||||||
|
req.namelen = (uint8)nlen;
|
||||||
|
memcpy(req.name, name, nlen);
|
||||||
|
req.len = 6 + nlen;
|
||||||
|
|
||||||
|
repl.len = sizeof(repl) - sizeof(uint16);
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xE300, &req, &repl);
|
||||||
|
if (neterrno) return(-1);
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
info->next_index = GET_16(repl.next);
|
||||||
|
memcpy(info->name, repl.fname, 14);
|
||||||
|
info->name[14] = '\0';
|
||||||
|
info->attr = repl.attr;
|
||||||
|
info->extattr = repl.extattr;
|
||||||
|
memcpy(info->raw, repl.raw, sizeof(info->raw));
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_ncp23_set(uint8 dhandle, char *name, FLAG_NWINFO *info, uint32 attrs)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
uint8 func;
|
||||||
|
uint8 attr;
|
||||||
|
uint8 extattr;
|
||||||
|
uint8 raw[76];
|
||||||
|
uint8 dhandle;
|
||||||
|
uint8 searchattr;
|
||||||
|
uint8 namelen;
|
||||||
|
uint8 name[255];
|
||||||
|
} req;
|
||||||
|
struct {
|
||||||
|
uint16 len;
|
||||||
|
} repl;
|
||||||
|
int nlen;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&repl, 0, sizeof(repl));
|
||||||
|
|
||||||
|
nlen = min(255, strlen(name));
|
||||||
|
|
||||||
|
req.func = 0x10;
|
||||||
|
req.attr = (uint8)(attrs & 0xff);
|
||||||
|
req.extattr = (uint8)((attrs >> 8) & 0xff);
|
||||||
|
memcpy(req.raw, info->raw, sizeof(req.raw));
|
||||||
|
req.dhandle = dhandle;
|
||||||
|
req.searchattr = 0x06;
|
||||||
|
req.namelen = (uint8)nlen;
|
||||||
|
memcpy(req.name, name, nlen);
|
||||||
|
req.len = 82 + nlen;
|
||||||
|
|
||||||
|
repl.len = 0;
|
||||||
|
|
||||||
|
neterrno = Net_Call(0xE300, &req, &repl);
|
||||||
|
if (neterrno) return(-1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_get_nw_attrs(char *name, uint32 *attrs, FLAG_NWINFO *info)
|
||||||
|
{
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
FLAG_NWINFO local;
|
||||||
|
|
||||||
|
if (flag_current_dhandle(&dhandle))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (!info) info = &local;
|
||||||
|
|
||||||
|
if (flag_ncp23_scan(dhandle, name, info))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (attrs)
|
||||||
|
*attrs = ((uint32)info->attr) | (((uint32)info->extattr) << 8);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flag_set_nw_attrs(char *name, uint32 attrs)
|
||||||
|
{
|
||||||
|
uint8 dhandle = 0;
|
||||||
|
FLAG_NWINFO info;
|
||||||
|
|
||||||
|
if (flag_current_dhandle(&dhandle))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (flag_ncp23_scan(dhandle, name, &info))
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
return(flag_ncp23_set(dhandle, name, &info, attrs));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef _A_NORMAL
|
#ifndef _A_NORMAL
|
||||||
#define _A_NORMAL 0x00
|
#define _A_NORMAL 0x00
|
||||||
#endif
|
#endif
|
||||||
@@ -76,29 +246,43 @@ static int flag_attr_mask(char *s, unsigned *setbits, unsigned *clearbits)
|
|||||||
if (!*p) return(-1);
|
if (!*p) return(-1);
|
||||||
|
|
||||||
if (flag_same(p, "RO")) {
|
if (flag_same(p, "RO")) {
|
||||||
if (set) *setbits |= _A_RDONLY;
|
if (set) {
|
||||||
else *clearbits |= _A_RDONLY;
|
*setbits |= NWFA_RO;
|
||||||
|
/*
|
||||||
|
* Novell FLAG also shows DI/RI for +RO on real NetWare.
|
||||||
|
* Those are byte2 flags and need NCP87/35 later.
|
||||||
|
*/
|
||||||
|
} else *clearbits |= NWFA_RO;
|
||||||
} else if (flag_same(p, "RW")) {
|
} else if (flag_same(p, "RW")) {
|
||||||
*clearbits |= _A_RDONLY;
|
*clearbits |= NWFA_RO;
|
||||||
|
} else if (flag_same(p, "S")) {
|
||||||
|
if (set) *setbits |= NWFA_S;
|
||||||
|
else *clearbits |= NWFA_S;
|
||||||
} else if (flag_same(p, "H")) {
|
} else if (flag_same(p, "H")) {
|
||||||
if (set) *setbits |= _A_HIDDEN;
|
if (set) *setbits |= NWFA_H;
|
||||||
else *clearbits |= _A_HIDDEN;
|
else *clearbits |= NWFA_H;
|
||||||
} else if (flag_same(p, "SY") || flag_same(p, "SYS") || flag_same(p, "SYSTEM")) {
|
} else if (flag_same(p, "SY") || flag_same(p, "SYS") || flag_same(p, "SYSTEM")) {
|
||||||
if (set) *setbits |= _A_SYSTEM;
|
if (set) *setbits |= NWFA_SY;
|
||||||
else *clearbits |= _A_SYSTEM;
|
else *clearbits |= NWFA_SY;
|
||||||
|
} else if (flag_same(p, "T")) {
|
||||||
|
if (set) *setbits |= NWFA_T;
|
||||||
|
else *clearbits |= NWFA_T;
|
||||||
} else if (flag_same(p, "A")) {
|
} else if (flag_same(p, "A")) {
|
||||||
if (set) *setbits |= _A_ARCH;
|
if (set) *setbits |= NWFA_A;
|
||||||
else *clearbits |= _A_ARCH;
|
else *clearbits |= NWFA_A;
|
||||||
|
} else if (flag_same(p, "RA")) {
|
||||||
|
if (set) *setbits |= NWFA_RA;
|
||||||
|
else *clearbits |= NWFA_RA;
|
||||||
|
} else if (flag_same(p, "WA")) {
|
||||||
|
if (set) *setbits |= NWFA_WA;
|
||||||
|
else *clearbits |= NWFA_WA;
|
||||||
} else if (flag_same(p, "N") || flag_same(p, "NORMAL")) {
|
} else if (flag_same(p, "N") || flag_same(p, "NORMAL")) {
|
||||||
*clearbits |= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);
|
*clearbits |= (NWFA_RO | NWFA_H | NWFA_SY | NWFA_A |
|
||||||
|
NWFA_S | NWFA_T | NWFA_RA | NWFA_WA);
|
||||||
} else if (flag_same(p, "ALL")) {
|
} else if (flag_same(p, "ALL")) {
|
||||||
/*
|
*setbits |= (NWFA_RO | NWFA_H | NWFA_SY | NWFA_A |
|
||||||
* Stage 1: Only DOS-visible bits are supported. NetWare-only bits
|
NWFA_S | NWFA_T | NWFA_RA | NWFA_WA);
|
||||||
* like S/T/P/RA/WA/CI/DI/RI need NCP support later.
|
} else if (flag_same(p, "P") || flag_same(p, "CI") ||
|
||||||
*/
|
|
||||||
*setbits |= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);
|
|
||||||
} else if (flag_same(p, "S") || flag_same(p, "T") || flag_same(p, "P") ||
|
|
||||||
flag_same(p, "RA") || flag_same(p, "WA") || flag_same(p, "CI") ||
|
|
||||||
flag_same(p, "DI") || flag_same(p, "RI")) {
|
flag_same(p, "DI") || flag_same(p, "RI")) {
|
||||||
fprintf(stderr, "Attribute not supported on this version of NetWare\n");
|
fprintf(stderr, "Attribute not supported on this version of NetWare\n");
|
||||||
return(1);
|
return(1);
|
||||||
@@ -113,25 +297,22 @@ static int flag_attr_mask(char *s, unsigned *setbits, unsigned *clearbits)
|
|||||||
static void flag_print_attrs(unsigned attr)
|
static void flag_print_attrs(unsigned attr)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Novell FLAG display order is not the same as help order.
|
* Novell order:
|
||||||
* Observed output:
|
* RO/RW S A H Sy T P RA WA CI DI RI
|
||||||
* [ Rw - A H Sy - -- -- -- -- DI RI ]
|
|
||||||
* Order:
|
|
||||||
* RO/RW, S, A, H, Sy, T, P, RA, WA, CI, DI, RI
|
|
||||||
*/
|
*/
|
||||||
fprintf(stdout, "[ ");
|
fprintf(stdout, "[ ");
|
||||||
fprintf(stdout, "%s ", (attr & _A_RDONLY) ? "RO" : "Rw");
|
fprintf(stdout, "%s ", (attr & NWFA_RO) ? "RO" : "Rw");
|
||||||
fprintf(stdout, "- "); /* S Shareable */
|
fprintf(stdout, "%c ", (attr & NWFA_S) ? 'S' : '-');
|
||||||
fprintf(stdout, "%c ", (attr & _A_ARCH) ? 'A' : '-');
|
fprintf(stdout, "%c ", (attr & NWFA_A) ? 'A' : '-');
|
||||||
fprintf(stdout, "%c ", (attr & _A_HIDDEN) ? 'H' : '-');
|
fprintf(stdout, "%c ", (attr & NWFA_H) ? 'H' : '-');
|
||||||
fprintf(stdout, "%s ", (attr & _A_SYSTEM) ? "Sy" : "-");
|
fprintf(stdout, "%s ", (attr & NWFA_SY) ? "Sy" : "-");
|
||||||
fprintf(stdout, "- "); /* T */
|
fprintf(stdout, "%c ", (attr & NWFA_T) ? 'T' : '-');
|
||||||
fprintf(stdout, "-- "); /* P */
|
fprintf(stdout, "-- "); /* P needs NCP87 */
|
||||||
fprintf(stdout, "-- "); /* RA */
|
fprintf(stdout, "%s ", (attr & NWFA_RA) ? "Ra" : "--");
|
||||||
fprintf(stdout, "-- "); /* WA */
|
fprintf(stdout, "%s ", (attr & NWFA_WA) ? "Wa" : "--");
|
||||||
fprintf(stdout, "-- "); /* CI */
|
fprintf(stdout, "-- "); /* CI needs NCP87 */
|
||||||
fprintf(stdout, "-- "); /* DI */
|
fprintf(stdout, "-- "); /* DI needs NCP87 */
|
||||||
fprintf(stdout, "-- "); /* RI */
|
fprintf(stdout, "-- "); /* RI needs NCP87 */
|
||||||
fprintf(stdout, "]");
|
fprintf(stdout, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +343,12 @@ static int flag_list(char *pattern)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
if (!(ff.attrib & _A_SUBDIR)) {
|
if (!(ff.attrib & _A_SUBDIR)) {
|
||||||
flag_display_one(ff.name, ff.attrib);
|
uint32 nwattrs;
|
||||||
|
|
||||||
|
if (flag_get_nw_attrs(ff.name, &nwattrs, NULL))
|
||||||
|
nwattrs = (uint32)ff.attrib;
|
||||||
|
|
||||||
|
flag_display_one(ff.name, (unsigned)nwattrs);
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
} while (!_dos_findnext(&ff));
|
} while (!_dos_findnext(&ff));
|
||||||
@@ -180,32 +366,36 @@ static int flag_apply(char *pattern, unsigned setbits, unsigned clearbits)
|
|||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
unsigned attr;
|
uint32 attrs;
|
||||||
unsigned newattr;
|
uint32 newattrs;
|
||||||
char fname[260];
|
char fname[260];
|
||||||
|
|
||||||
if (ff.attrib & _A_SUBDIR) continue;
|
if (ff.attrib & _A_SUBDIR) continue;
|
||||||
|
|
||||||
strmaxcpy(fname, ff.name, sizeof(fname) - 1);
|
strmaxcpy(fname, ff.name, sizeof(fname) - 1);
|
||||||
|
|
||||||
if (_dos_getfileattr(fname, &attr)) {
|
if (flag_get_nw_attrs(fname, &attrs, NULL))
|
||||||
attr = ff.attrib;
|
attrs = (uint32)ff.attrib;
|
||||||
}
|
|
||||||
|
|
||||||
newattr = (attr | setbits) & ~clearbits;
|
newattrs = (attrs | setbits) & ~clearbits;
|
||||||
|
|
||||||
if (newattr != attr) {
|
if (newattrs != attrs) {
|
||||||
if (_dos_setfileattr(fname, newattr)) {
|
if (flag_set_nw_attrs(fname, newattrs)) {
|
||||||
fprintf(stderr, "You don't have rights to change : %s\n", fname);
|
/*
|
||||||
continue;
|
* Fallback for local/DOS-visible bits. This keeps old behavior alive.
|
||||||
|
*/
|
||||||
|
unsigned dosattr = (unsigned)(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attr = newattr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (flag_get_nw_attrs(fname, &attrs, NULL))
|
||||||
* Novell FLAG prints the resulting file entry after the command.
|
attrs = newattrs;
|
||||||
*/
|
|
||||||
flag_display_one(fname, attr);
|
flag_display_one(fname, (unsigned)attrs);
|
||||||
shown++;
|
shown++;
|
||||||
|
|
||||||
} while (!_dos_findnext(&ff));
|
} while (!_dos_findnext(&ff));
|
||||||
|
|||||||
Reference in New Issue
Block a user