Commit 9ec1ae87 authored by Stewart Brodie's avatar Stewart Brodie
Browse files

New *LMLS command.

  Fix for ./.. files in short filename shares.
  Long multiply now provided in assembler.
Detail:
  *LMLS is a new filesystem-specific command which performs the same
    task as "smbclient -L" does under UNIX - ie. listing all the shares
    available on the specified host.
  When enumerating the shares on a remote server, LanManFS now remembers
    all the printers, IPC, device and disc shares (for *LMLS to output).
  The 32x32->64 multiply routine is now provided in assembler instead of
    the previous huge amount of obscure C taken from NSPRLib.  This is
    more understandable (and almost certainly far smaller and quicker
    and doesn't need a hack to stop the compiler mis-optimising it!)
  Old short filename shares still had problems with the . and .. file
    filtering.  Programmer fault there - should've let the compiler do
    the optimisations :-)
  Server info string fixed to byte-reverse the port numbers when printing
    the string into the info buffer.  Now claims to be talking to port 139
    as it should.
Admin:
  Tested in general desktop use for several days, plus experimental versions
    tested in other boot ROMs.

Version 2.03. Tagged as 'LanManFS-2_03'
parent 91cb8981
/* (2.02)
/* (2.03)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 2.02
#define Module_MajorVersion_CMHG 2.03
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 18 Feb 1999
#define Module_Date_CMHG 01 Mar 1999
#define Module_MajorVersion "2.02"
#define Module_Version 202
#define Module_MajorVersion "2.03"
#define Module_Version 203
#define Module_MinorVersion ""
#define Module_Date "18 Feb 1999"
#define Module_Date "01 Mar 1999"
......@@ -181,7 +181,7 @@ static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
#endif
if ( entry[9] == '.' ) {
/* Ignore '.' and '..' directories */
if (entry[10] == '.' && entry[10] == '\0' || entry[11] == '\0') {
if (entry[10] == '.' && entry[11] == '\0' || entry[10] == '\0') {
return OK;
}
}
......
......@@ -79,6 +79,10 @@ static void stopcallbacks(void);
static _kernel_oserror *LM_init_phase_2(void);
/* --------------------- */
struct LMvars LM_Vars;
/* ---------------------------------- */
int LM_pw; /* Our module's private word */
......@@ -367,6 +371,19 @@ static _kernel_oserror *Cmd_FREE ( const char *args )
return e;
}
/* --------------------- */
static _kernel_oserror *Cmd_LMLS ( const char *args )
{
char *argv[1];
if (GetArgs(args, argv, sizeof(argv)/sizeof(*argv)) == 0) {
return Omni_DumpServers();
}
else {
return Omni_DumpShares(argv[0]);
}
}
/* --------------------- */
static _kernel_oserror *Cmd_CONNECT ( const char *args )
......@@ -415,9 +432,6 @@ static _kernel_oserror *Cmd_DISCONNECT ( const char *args )
return Xlt_Error (res);
}
/* --------------------- */
struct LMvars LM_Vars;
/* --------------------- */
......@@ -541,12 +555,12 @@ static _kernel_oserror *Cmd_LMSERVER ( const char *args )
if ( argv[1] == NULL ) /* Just name of server */
{
Omni_AddInfo ( OAI_SERVER, argv[0], NULL );
Omni_AddInfo ( OAI_SERVER, argv[0], NULL, NULL );
}
else
{
for ( i=1; i < MAX_ARGS && argv[i] != NULL; i++ )
Omni_AddInfo ( OAI_DISK, argv[0], argv[i] );
Omni_AddInfo ( OAI_DISK, argv[0], argv[i], NULL );
}
Omni_RecheckInfo (RI_SERVERS);
......@@ -565,12 +579,12 @@ static _kernel_oserror *Cmd_LMPRINTERS ( const char *args )
if ( argv[1] == NULL ) /* Just name of server */
{
Omni_AddInfo ( OAI_SERVER, argv[0], NULL );
Omni_AddInfo ( OAI_SERVER, argv[0], NULL, NULL );
}
else
{
for ( i=1; i < MAX_ARGS && argv[i] != NULL; i++ )
Omni_AddInfo ( OAI_PRINTER, argv[0], argv[i] );
Omni_AddInfo ( OAI_PRINTER, argv[0], argv[i], NULL );
}
Omni_RecheckInfo (RI_SERVERS);
......@@ -709,7 +723,7 @@ static _kernel_oserror *Cmd_NBNSIP( const char *args )
typedef _kernel_oserror * (*CommandFnPtr) ( const char *args );
#define MAX_CMDS 14
#define MAX_CMDS 15
static CommandFnPtr Cmd_Dispatch[MAX_CMDS] =
{
Cmd_LANMAN,
......@@ -725,7 +739,8 @@ static CommandFnPtr Cmd_Dispatch[MAX_CMDS] =
Cmd_FS,
Cmd_LMTRANSPORT,
Cmd_NBNSIP,
Cmd_FREE
Cmd_FREE,
Cmd_LMLS
};
#ifdef TRACE
......@@ -751,6 +766,7 @@ static void chk_commands(void)
chk_a_command(Cmd_LMTRANSPORT, CMD_LMTransport);
chk_a_command(Cmd_NBNSIP, CMD_LMNameServer);
chk_a_command(Cmd_FREE, CMD_Free);
chk_a_command(Cmd_LMLS, CMD_LMls);
}
#endif
......
......@@ -1960,7 +1960,7 @@ EXPORT char * _NB_DescribeLink ( hSESSION hS )
return NULL;
sprintf(namebuf, "%s port %d", inet_ntoa(pNS->rmt_addr.sin_addr),
pNS->rmt_addr.sin_port );
htons(pNS->rmt_addr.sin_port ));
return namebuf;
}
......
......@@ -60,7 +60,7 @@
#include "omni.h"
#include "LanMan_MH.h"
#define INFO_STR_LEN 32
#define INFO_STR_LEN 64
/* Length of info string kept about servers & mounts */
/* SWI definitions */
......@@ -82,6 +82,10 @@
#define S_VALID_TAG 0x4938EE2B
/* Tag for a valid current mount */
#define M_VALID_TAG 0x9384EBE2
/* Tag for an IPC mount */
#define I_VALID_TAG 0x24435049
/* Tag for comms device mount */
#define C_VALID_TAG 0x314D4F43
typedef struct namelist NAMELIST; /* Our general holds-everything list */
......@@ -91,6 +95,8 @@ struct server_extra_info
{
NAMELIST *known_disks; /* -> list of D_VALID_TAG records */
NAMELIST *known_printers; /* -> list of P_VALID_TAG records */
NAMELIST *known_ipc; /* list of I_VALID_TAG records */
NAMELIST *known_comms; /* list of C_VALID_TAG records */
char info_string[INFO_STR_LEN];
};
......@@ -106,6 +112,12 @@ struct mount_extra_info
char connected; /* Non-zero as soon as it is mounted */
};
/* Information on a share */
struct share_extra_info
{
char info_string[INFO_STR_LEN];
};
/* Multipurpose name-list structure */
struct namelist
......@@ -118,6 +130,7 @@ struct namelist
{
struct mount_extra_info mount;
struct server_extra_info server;
struct share_extra_info share;
} u;
struct namelist *master_link;
......@@ -587,62 +600,6 @@ typedef struct fspc_64 {
unsigned lo, hi;
} fspc_64;
/* Multiply macro taken from NSPRLib */
#define LL_MUL(r, a, b) { \
fspc_64 _a, _b; \
_a = a; _b = b; \
LL_MUL32(r, _a.lo, _b.lo); \
(r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
}
#define PR_BIT(n) ((unsigned)1 << (n))
#define PR_BITMASK(n) (PR_BIT(n) - 1)
#define _lo16(a) ((a) & PR_BITMASK(16))
#define _hi16(a) ((a) >> 16)
#define LL_MUL32(r, a, b) { \
unsigned _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
_a1 = _hi16(a), _a0 = _lo16(a); \
_b1 = _hi16(b), _b0 = _lo16(b); \
_y0 = _a0 * _b0; \
_y1 = _a0 * _b1; \
_y2 = _a1 * _b0; \
_y3 = _a1 * _b1; \
_y1 += _hi16(_y0); /* can't carry */ \
_y1 += _y2; /* might carry */ \
if (_y1 < _y2) \
_y3 += (unsigned)(PR_BIT(16)); /* propagate */ \
(r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \
(r).hi = _y3 + _hi16(_y1); \
}
#ifdef __CC_NORCROFT
/* No way of checking version number though.
* Version 5.11 of the compiler should be OK because I fixed this bug
* in that version [sbrodie]
*/
static void _Omni_ForceCSESync(void) {}
#else
# define _Omni_ForceCSESync() ((void)0)
#endif
#ifdef __CC_NORCROFT
/* May as well optimise this a bit */
__value_in_regs
#endif
static fspc_64 Omni_Multiply64(uint plo1, uint plo2)
{
fspc_64 p1, p2, res;
p1.hi = p2.hi = 0;
p1.lo = plo1;
p2.lo = plo2;
_Omni_ForceCSESync();
LL_MUL(res, p1, p2);
_Omni_ForceCSESync();
return res;
}
static err_t Omni_FreeSpace64 ( int mount_id, int *success,
fspc_64 *freespace_out, fspc_64 *usedspace_out, fspc_64 *totspace_out )
{
......@@ -653,9 +610,12 @@ static err_t Omni_FreeSpace64 ( int mount_id, int *success,
if ( res != OK )
return res;
*freespace_out = Omni_Multiply64(DSR.freeblks, DSR.blksize);
*totspace_out = Omni_Multiply64(DSR.totalblks, DSR.blksize);
*usedspace_out = Omni_Multiply64(DSR.totalblks - DSR.freeblks, DSR.blksize);
/* OmniS_FastMultiply64 does a 32x32 bit multiply and stores the 64-bit
* result in the supplied pointer (1st param)
*/
OmniS_FastMultiply64(freespace_out, DSR.freeblks, DSR.blksize);
OmniS_FastMultiply64(totspace_out, DSR.totalblks, DSR.blksize);
OmniS_FastMultiply64(usedspace_out, DSR.totalblks - DSR.freeblks, DSR.blksize);
*success = 0;
return OK;
......@@ -1525,6 +1485,14 @@ void Omni_ClearLists ( void )
DeleteFromList ( &(pNLsrv->u.server.known_printers),
pNLsrv->u.server.known_printers );
while ( pNLsrv->u.server.known_ipc != NULL )
DeleteFromList ( &(pNLsrv->u.server.known_ipc),
pNLsrv->u.server.known_ipc );
while ( pNLsrv->u.server.known_comms != NULL )
DeleteFromList ( &(pNLsrv->u.server.known_comms),
pNLsrv->u.server.known_comms );
/* If the server has no active mounts left, delete it too */
if ( pNLsrv->u.server.known_disks == NULL )
......@@ -1584,9 +1552,10 @@ static void showlist ( NAMELIST *pNL )
/* ------------------------------ */
void Omni_AddInfo ( int flags, char *serv_name, char *string )
void Omni_AddInfo ( int flags, char *serv_name, char *string, char *comment )
{
NAMELIST *pNLsrv;
NAMELIST *pNLsrv, **list;
int tag = 0;
pNLsrv = AddToList ( &ServerList, S_VALID_TAG, serv_name );
if ( pNLsrv == NULL ) /* Couldn't add it */
......@@ -1598,20 +1567,98 @@ void Omni_AddInfo ( int flags, char *serv_name, char *string )
/* Amend information about server */
if ( string != NULL )
strcpyn ( pNLsrv->u.server.info_string, string, INFO_STR_LEN );
break;
return;
case OAI_DISK:
AddToList ( &(pNLsrv->u.server.known_disks),
D_VALID_TAG, string);
tag = D_VALID_TAG;
list = &pNLsrv->u.server.known_disks;
break;
case OAI_PRINTER:
AddToList ( &(pNLsrv->u.server.known_printers),
P_VALID_TAG, string );
tag = P_VALID_TAG;
list = &pNLsrv->u.server.known_printers;
break;
case OAI_IPC:
tag = I_VALID_TAG;
list = &pNLsrv->u.server.known_ipc;
break;
case OAI_DEVICE:
tag = C_VALID_TAG;
list = &pNLsrv->u.server.known_comms;
break;
default:
return;
}
AddToList ( list, tag, string );
pNLsrv = FindInList(*list, string);
if (pNLsrv != NULL) {
if (comment != NULL) {
strcpyn ( pNLsrv->u.share.info_string, comment, INFO_STR_LEN );
}
else {
pNLsrv->u.share.info_string[0] = '\0';
}
}
}
_kernel_oserror *Omni_DumpServers(void)
{
err_t res;
int token;
char *eptr;
res = Omni_ListServers(0,0,0,&eptr,&token);
if (res != OK) return Xlt_Error(res);
Omni_Debug();
return NULL;
}
static void Omni_DumpSharesPrint(NAMELIST *pNL, const char *type)
{
for (; pNL != NULL; pNL = pNL->next) {
printf(" %-16s %-10s %s\n", pNL->name, type, pNL->u.share.info_string);
}
}
static void Omni_DumpServersPrint(NAMELIST *pNL)
{
for (; pNL != NULL; pNL = pNL->next) {
printf(" %-16s %s\n", pNL->name, pNL->u.server.info_string);
}
}
_kernel_oserror *Omni_DumpShares(char *server_name)
{
err_t res;
int token;
char *eptr;
NAMELIST *pserv;
/* Don't give a XXXX about getting the info back - just force the RPC
* call to execute and stuff all the data into the data structures and
* we'll go through the data structures ourselves, tvm.
*/
res = Omni_ListMounts(0, 0, 0, 0, server_name, &eptr, &token);
if (res != OK) return Xlt_Error(res);
pserv = FindInList(ServerList, server_name);
if (pserv != NULL && pserv->tag == S_VALID_TAG) {
printf(" Sharename Type Comment\n"
" --------- ---- -------\n\n");
Omni_DumpSharesPrint(pserv->u.server.known_disks, "Disk");
Omni_DumpSharesPrint(pserv->u.server.known_printers, "Printer");
Omni_DumpSharesPrint(pserv->u.server.known_ipc, "IPC");
Omni_DumpSharesPrint(pserv->u.server.known_comms, "Comms");
printf("\n Server Comment\n"
" ------ -------\n");
Omni_DumpServersPrint(ServerList);
}
return NULL;
}
/* ------------------- */
......
......@@ -152,7 +152,7 @@ err_t Prn_CreateJob ( char *servname, char *prnname, char *userid,
if ( res != OK )
return res;
Omni_AddInfo ( OAI_PRINTER, servname, prnname );
Omni_AddInfo ( OAI_PRINTER, servname, prnname, NULL );
sprintf ( namebuf, "%05d", ++JobSerialNo );
/* Open printer spool file */
......
......@@ -126,12 +126,13 @@ static int getword ( BYTE *p )
}
/* ----------------- */
#ifndef OMIT_UNUSED_FNS
#if 0
static int getlong ( BYTE *p )
{
return ( p[0] + (p[1] << 8) + (p[2] << 16)+ (p[3] << 24));
}
#endif
/* ----------------- */
static BYTE *getpointer ( BYTE *p )
......@@ -163,7 +164,7 @@ static bool check_hidden ( char *name )
static err_t RPC_EnumSharesOnConnection ( char drv, char *server )
{
BYTE *p;
int i;
int i, co;
err_t res;
/* Assemble parameters for RPC call */
......@@ -187,6 +188,8 @@ static err_t RPC_EnumSharesOnConnection ( char drv, char *server )
if ( getword(p) != 0 ) /* API return code; 0 = success */
return ERPCERROR; /* Otherwise, call it 'generic' error */
co = getword(p+2); /* Comment offset adjustment - ( why?? ) */
i = getword(p+4); /* Number of records returned */
if ( i*20 > TP.data_out_len ) /* Silly values! */
return EDATALEN;
......@@ -200,15 +203,25 @@ static err_t RPC_EnumSharesOnConnection ( char drv, char *server )
/* p is the start of the record. The first 13 bytes
are a share name + null termination. If the share name
ends in '$', it is hidden and should not be listed.
[sbrodie: ... except if it's an IPC share, I've decided. Also
we store the comments too for *lanman:lmls to display. Why is there
a mystical word in the returned param block which is subtracted from
the offset field? Dunno, but SAMBA does it and Windows 98 needs it.]
*/
int shrtype = getword(p+14);
int commoffset = getword(p+16);
char *comment = commoffset ? ((char *) TP.data_out_buf + commoffset - co) : 0;
if ( check_hidden( (char *)p) )
if ( shrtype == SHR_IPC || check_hidden( (char *)p) )
{
if ( shrtype == SHR_DISK )
Omni_AddInfo ( OAI_DISK, server, (char *)p );
Omni_AddInfo ( OAI_DISK, server, (char *)p, comment );
else if ( shrtype == SHR_PRINTER )
Omni_AddInfo ( OAI_PRINTER, server, (char *)p );
Omni_AddInfo ( OAI_PRINTER, server, (char *)p, comment );
else if ( shrtype == SHR_IPC )
Omni_AddInfo ( OAI_IPC, server, (char *)p, comment );
else if ( shrtype == SHR_COMM )
Omni_AddInfo ( OAI_DEVICE, server, (char *)p, comment );
}
p += 20;
}
......@@ -222,6 +235,7 @@ static err_t RPC_EnumServersOnConnection ( char drv, char *domain )
{
err_t res;
BYTE *p;
int co;
int i;
/* NetServerEnum2 */
......@@ -246,6 +260,8 @@ static err_t RPC_EnumServersOnConnection ( char drv, char *domain )
if ( getword(p) != 0 ) /* API return code; 0 = success */
return ERPCERROR;
co = getword(p+2);
i = getword(p+4); /* Number of records returned */
if ( i*26 > TP.data_out_len ) /* Silly values! */
return EDATALEN;
......@@ -259,8 +275,10 @@ static err_t RPC_EnumServersOnConnection ( char drv, char *domain )
/* p is the start of the record. The first 16 bytes
are a server name + null termination.
*/
int commoffset = getword(p+22);
char *comment = commoffset ? ((char *) TP.data_out_buf + commoffset - co) : 0;
Omni_AddInfo ( OAI_SERVER, (char *)p, NULL );
Omni_AddInfo ( OAI_SERVER, (char *)p, comment, NULL );
p += 26;
}
......@@ -282,7 +300,7 @@ err_t RPC_EnumerateShares ( char *server )
if ( res != OK )
return debug_err( res, "(EnumShares) could not log on to", server );
Omni_AddInfo ( OAI_SERVER, server, SMB_GetConnInfo(drv, GCI_SERVERINFO) );
Omni_AddInfo ( OAI_SERVER, server, SMB_GetConnInfo(drv, GCI_SERVERINFO), NULL );
res = RPC_EnumSharesOnConnection ( drv, server );
......
......@@ -144,6 +144,13 @@ command-keyword-table: LM_Command
Free(min-args:0, max-args:1,
help-text: "*Free displays the total free space on a LanManFS share",
invalid-syntax: "Syntax:\t*Free [<disc spec.>]\r",
fs-command:,
),
LMls(min-args:0, max-args:1,
help-text: "*LMls displays the servers in the current workgroup or\r"
"the shares on the given server",
invalid-syntax: "Syntax:\t*LMls [server]\r",
fs-command:,
)
......@@ -55,17 +55,22 @@ extern _kernel_oserror *Omni_FreeOp_SWI ( _kernel_swi_regs *R );
extern void Omni_Debug(void);
extern _kernel_oserror *Omni_DumpShares(char *server_name);
extern _kernel_oserror *Omni_DumpServers(void);
extern void Omni_AddInfo ( int flags, char *server, char *descr );
extern void Omni_AddInfo ( int flags, char *server, char *descr, char *comment );
#define OAI_SERVER 0
#define OAI_DISK 1
#define OAI_PRINTER 2
#define OAI_DEVICE 3
#define OAI_IPC 4
/* These routines are actually in S.Interface */
extern void OmniS_Suicide (char *modname);
extern void OmniS_ResourceInit (void);
extern void OmniS_ResourceShutdown (void);
extern void OmniS_ResFSStarting(int R2, int R3);
extern void OmniS_FastMultiply64(void *result, int arg1, int arg2);
/* OmniClient SWI definitions --------------- */
#define Omni_base 0x4A200
......
......@@ -231,6 +231,30 @@ CollectCallbacks
LDMFD SP!, {PC}^
; Long multiplier ----------------------------------------
; Taken from Acorn Assembler manual.
; extern void OmniS_FastMultiply64(fspc_64 *, unsigned, unsigned);
EXPORT OmniS_FastMultiply64
OmniS_FastMultiply64
STMFD sp!, {lr}
MOVS lr, a2, LSR #16
BIC a2, a2, lr, LSL #16
MOV ip, a3, LSR #16
BIC a3, a3, ip, LSL #16
MUL a4, a2, a3
MUL a3, lr, a3
MUL a2, ip, a2
MULNE lr, ip, lr
ADDS a2, a2, a3
ADDCS lr, lr, #&10000
ADDS a4, a4, a2, LSL #16
ADC lr, lr, a2, LSR #16
STMIA a1, {a4, lr}
LDMFD sp!, {pc}^
; Resources ----------------------------------------------
; This is Acorn's sorry excuse for the lack of a resource compiler.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment