Source
...
Target
Commits (2)
  • Ben Avison's avatar
    Compatibility change for Microsoft security fix MS09-001. · 3ba506cd
    Ben Avison authored
    Detail:
      Security fix MS09-001 (detailed in Microsoft Knowledge base article KB958687)
      fixes some vulnerabilities in the SMB protocol which LanManFS uses. This
      highlighted an error in SMB_WriteRaw which reported zero data bytes but then
      supplied an offset to the non existant bytes: this is now faulted by Windows.
      As there are no data bytes, the offset should also be zero.
    Admin:
      Fix received from Rob Sprowson 2009-01-19.
    
    Version 2.31. Tagged as 'LanManFS-2_31'
    3ba506cd
  • Ben Avison's avatar
    Multiple fixes. · 186192a3
    Ben Avison authored
    Detail:
      Too many to list here: see doc/RPSChanges.
    Admin:
      Received from Rob Sprowson approx 2009-02-08. Builds, but not tested by ROOL.
    
    Version 2.32. Tagged as 'LanManFS-2_32'
    186192a3
......@@ -14,4 +14,4 @@
|
Dir <Obey$Dir>
wimpslot 4000k
amu_machine rm.LanManFSD OPTIONS=-DCHECK_ARMBOOT_EXISTS SPRITES=RAM
amu_machine rm.LanManFSD OPTIONS=-DCHECK_ARMBOOT_EXISTS ROMSPRITES=FALSE
/* (2.30)
/* (2.32)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.68.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 2.30
#define Module_MajorVersion_CMHG 2.32
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 16 Feb 2004
#define Module_Date_CMHG 15 Apr 2009
#define Module_MajorVersion "2.30"
#define Module_Version 230
#define Module_MajorVersion "2.32"
#define Module_Version 232
#define Module_MinorVersion ""
#define Module_Date "16 Feb 2004"
#define Module_Date "15 Apr 2009"
#define Module_ApplicationDate "16-Feb-04"
#define Module_ApplicationDate "15-Apr-09"
#define Module_ComponentName "LanManFS"
#define Module_ComponentPath "RiscOS/Sources/Networking/Omni/Protocols/LanManFS"
#define Module_FullVersion "2.30"
#define Module_HelpVersion "2.30 (16 Feb 2004)"
#define Module_LibraryVersionInfo "2:30"
#define Module_FullVersion "2.32"
#define Module_HelpVersion "2.32 (15 Apr 2009)"
#define Module_LibraryVersionInfo "2:32"
......@@ -40,6 +40,7 @@
#include "xlate.h"
#include "omni.h"
#include "LanMan.h"
#include "LMVars.h"
/* "Default" filetype logic ------------------------------------- */
......@@ -54,14 +55,13 @@ struct ext_type
int type;
};
static struct ext_type FTypes[] =
static const struct ext_type FTypes[] =
{
{ "TXT", 0xFFF }, /* Text */
{ "C", 0xFFF },
{ "H", 0xFFF },
{ "ASM", 0xFFF },
{ "ARC", 0xDDC }, /* Spark */
{ "TIF", 0xFF0 }, /* TIFF File */
{ "JPG", 0xC85 }, /* JPEG */
{ "PS", 0xFF5 }, /* Postscript */
{ NULL, 0 }
};
......@@ -70,7 +70,7 @@ static struct ext_type FTypes[] =
static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
{
struct ext_type *pET;
const struct ext_type *pET;
int ftype;
_kernel_swi_regs rset ;
......@@ -86,11 +86,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
leafname = strchr(leafname, '.');
if ( leafname == NULL ) /* No extension */
{
debug1("No suffix,assuming Text filetype for '%s'\n", leafname );
ra->loadaddr = Default_FileType << 8;
return;
}
{
debug2("Assuming filetype %03x for '%s' due to no suffix\n", LM_Vars.default_type, leafname );
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(LM_Vars.default_type << 8);
return;
}
leafname++; /* Skip '.' */
......@@ -99,11 +100,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
rset.r[1] = (int)leafname;
rset.r[2] = MMM_TYPE_RISCOS;
if (_kernel_swi(MimeMap_Translate, &rset, &rset) == NULL)
{
ra->loadaddr = rset.r[3] << 8;
debug2("Mimemap gave type %X for '%s'\n", rset.r[3], leafname );
return;
}
{
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(rset.r[3] << 8);
debug2("Mimemap gave type %X for '%s'\n", rset.r[3], leafname );
return;
}
/* Look through the feable small table */
for ( pET = FTypes; pET->ext != NULL; pET++ )
......@@ -111,7 +113,7 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
if ( strcmp ( pET->ext, leafname ) == 0 )
{
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(pET->type << 8);
(pET->type << 8);
return;
}
}
......@@ -365,7 +367,6 @@ err_t Attr_GetInfo ( char *filename, char *leafname,
return Attr_GetInfoX2 ( filename, leafname, pRA );
#endif
if ( SetFileName(filename) != OK )
return EBADNAME;
......
......@@ -39,53 +39,23 @@
#include "NameCache.h"
/* Some globals ================================== */
#define NAMEBUF_LEN (2*DOS_NAME_LEN)
#define name_R(x) ((char *)R[x])
static char DOSnamebuf [NAMEBUF_LEN];
static char DOSnamebuf[NAMEBUF_LEN];
static err_t FileGetAttribs ( char *filename, DOS_ATTRIBS *pda,
RISCOS_ATTRIBS *pra );
#define name_R(x) ((char *)R[x])
/* Func subroutines=============================================== */
#define NAMES_ONLY 14
#define MOST_INFO 15
#define ALL_INFO 19
/* Read-directory subroutines --------- */
/* The directory entries can take one of three forms, taking up
a variable degree of space
NAMES_ONLY - 16 bytes (12 bytes of name, plus 0 terminator, plus
word rounding).
MOST_INFO - 36 bytes
ALL_INFO - 44 bytes
*/
static char RD_CurrentPath[DOS_NAME_LEN];
/* Read-directory subroutines ======================================= */
static int RD_Reason;
static char *RD_BufPtr;
static int RD_BufLen;
static int RD_ReqCount; /* No. of entries required */
static int RD_ReqOffset; /* Offset of currently required dir entry */
static int RD_CurOffset; /* Offset of next entry to be given to
Dir_CallbackFn */
/* ---------------- */
static int RD_CurCount; /* No. of entries given */
/* SNB: the blocks being written are those required by:
* NAMES_ONLY => OS_GBPB 9 => (FSEntry_Func 14)
* MOST_INFO => OS_GBPB 10 => (FSEntry_Func 15)
* ALL_INFO => OS_GBPB 11 => (FSEntry_Func 19)
/* Write one directory entry to the supplied buffer
* The directory entries can take one of three forms, taking up
* a variable degree of space
*/
static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
{
......@@ -97,7 +67,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
int *IntPtr;
#ifndef LONGNAMES
(void) format;
(void) format;
#else
if (format == 1) {
Xlt_ExpandSearchEntryX2(entry, DOSnamebuf, namebuf, &da, &ra);
......@@ -107,17 +77,18 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
Xlt_ExpandSearchEntry(entry, DOSnamebuf, namebuf, &da, &ra);
name_len = strlen(namebuf) + 1;
debug1("WriteEntry (%s)\n", namebuf);
switch ( reason )
{
case NAMES_ONLY:
case FSEntry_Func_Reason_ReadDirectoryEntries:
rec_len = name_len;
if (rec_len <= RD_BufLen) {
memcpy(ptr, namebuf, name_len);
}
break;
case MOST_INFO:
case FSEntry_Func_Reason_ReadDirectoriesAndInformation:
rec_len = (20+name_len+3) & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr;
......@@ -130,7 +101,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
}
break;
case ALL_INFO:
case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation:
rec_len = (29+name_len)+3 & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr;
......@@ -151,10 +122,10 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
}
if (rec_len > RD_BufLen) {
debug2("WriteEntry detects a buffer overflow (%d > %d)\n",
debug2("WriteEntry detects a buffer overflow (%d > %d)\n",
rec_len, RD_BufLen);
RD_BufLen = -1;
return NULL;
RD_BufLen = -1;
return NULL;
}
RD_BufLen -= rec_len;
......@@ -163,7 +134,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
/* ------------------------------ */
static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
static err_t Dir_CallbackFn ( BYTE *entry, int format, bool *taken, void *pw )
{
(void) pw;
#ifdef LONGNAMES
......@@ -187,48 +158,49 @@ static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
}
}
// debug3 ("Entry: current %d req %d count %d\n",
// RD_CurOffset, RD_ReqOffset, RD_ReqCount );
if ( RD_ReqOffset == RD_CurOffset )
*taken = false;
if ( RD_ReqCount > 0 )
{
if ( RD_ReqCount > 0 )
{
char *w_result = WriteEntry ( RD_Reason, RD_BufPtr, entry, format );
if (w_result != NULL) {
RD_BufPtr = w_result;
RD_ReqCount--;
RD_ReqOffset++;
}
else {
debug0("Oh dear - client ran out of buffer space!\n");
RD_CurOffset++;
return EOUTOFMEM;
}
char *w_result = WriteEntry ( RD_Reason, RD_BufPtr, entry, format );
if (w_result != NULL) {
RD_BufPtr = w_result;
RD_ReqCount--;
RD_CurCount++;
*taken = true;
}
else {
debug0("Oh dear - client ran out of buffer space!\n");
return EOUTOFMEM;
}
}
RD_CurOffset++;
return OK;
}
/* ----------------- */
/* Called in 2 situations
* - starting a search from scratch (dir_offset = 0)
* - continuing a search (dir_offset != 0)
* The underlying SMB routine must track whether it has been called
* recursively or from within Xlt_NameROtoDOSX2_sub and deal with
* abandoning searches appropriately.
*/
static err_t Func_ReadDir ( int reason, char *path_name, char *buffer,
int n_names, int dir_offset, int buflen, int *pOutNread,
int *pOutNextOffset )
{
static Transact_SearchContext scon;
int tmp;
err_t res;
static Transact_SearchContext con;
int one_name;
err_t res;
debug2 ( "\n\n>> ReadDir reason %d path %s", reason, path_name );
debug2 ( " offset %d count %d\n", dir_offset, n_names );
debug2 ( " offset %d count %d", dir_offset, n_names );
debug1 ( " buflen %d\n", buflen);
/* Make sure the number of names we read will fit into buffer ---- */
tmp = (reason == NAMES_ONLY) ? 16 :
(reason == MOST_INFO) ? 36 : 44;
/* Make sure the number of names we read will fit into buffer */
one_name = (reason == FSEntry_Func_Reason_ReadDirectoryEntries) ? 16 :
(reason == FSEntry_Func_Reason_ReadDirectoriesAndInformation) ? 36 : 44;
#ifdef LONGNAMES
/* Of course, the above calculation assumes that the filename is at most
......@@ -245,132 +217,119 @@ static err_t Func_ReadDir ( int reason, char *path_name, char *buffer,
* unnecessary buffer overruns - especially when there are not very
* many files with long names or even no files with long names.
*/
/* There is no code inside this #ifdef - it just marks my comment. */
#endif
if ( n_names*tmp > buflen ) n_names = buflen/tmp;
if ( (n_names * one_name) > buflen ) n_names = buflen/one_name;
if ( n_names <= 0 ) return EBADPARAM;
debug1( "Adjusted count=%d\n", n_names );
RD_Reason = reason;
RD_BufPtr = buffer;
RD_BufLen = buflen;
RD_CurCount = 0;
RD_ReqCount = n_names;
RD_ReqOffset = dir_offset;
debug1("Actual count=%d\n", n_names );
/* Convert path adding wildcard search spec */
res = Xlt_ConvertPath( path_name, DOSnamebuf );
if ( res != OK ) return res;
tmp = strlen(DOSnamebuf);
if ( DOSnamebuf[strlen( DOSnamebuf ) - 1] != '\\' )
strcat( DOSnamebuf, "\\");
#ifdef LONGNAMES
if ( DOSnamebuf[tmp-1] == '\\' )
strcpy( DOSnamebuf+tmp, "*" );
else
strcpy( DOSnamebuf+tmp, "\\*" );
strcat( DOSnamebuf, "*" );
#else
if ( DOSnamebuf[tmp-1] == '\\' )
strcpy( DOSnamebuf+tmp, "????????.???" );
else
strcpy( DOSnamebuf+tmp, "\\????????.???" );
strcat( DOSnamebuf, "????????.???" );
#endif
/* Start a new search? ----------------------------------- */
if ( RD_ReqOffset == 0 || /* New start */
RD_ReqOffset < RD_CurOffset || /* Going back in search */
strcmp(DOSnamebuf, RD_CurrentPath) != 0 ) /* New directory */
/* Start a new search? */
if (dir_offset == 0)
{
debug1("\n>> Start search (%s)\n", DOSnamebuf);
strcpy ( RD_CurrentPath, DOSnamebuf);
RD_CurOffset = 0;
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount+RD_ReqOffset,
Dir_CallbackFn, NULL, &scon );
debug2( ">> Start search (%s) count %d\n", DOSnamebuf, RD_ReqCount);
con.resume_key = 0;
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
Dir_CallbackFn, NULL, &con );
}
else
else {
con.resume_key = dir_offset;
res = OK;
}
/* Continue search, if needs be */
while ( res == OK && /* More names available */
RD_ReqCount > 0 ) /* More names wanted */
{
debug0("\n>> Continue search\n");
res = SMB_ReadDirEntries ( NULL, RD_ReqCount+RD_ReqOffset-RD_CurOffset,
Dir_CallbackFn, NULL, &scon );
debug3( ">> Continue search (%s) count %d resume %08x\n", DOSnamebuf, RD_ReqCount, con.resume_key);
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
Dir_CallbackFn, NULL, &con );
}
/* Process results */
if (res == EOUTOFMEM && RD_BufLen == -1) {
/* Special result when client buffer space exhausted */
debug0("Client buffer space was exhausted\n");
res = OK;
}
debug2("End search, res=%d RD_ReqCount=%d\n", res, RD_ReqCount);
if ( res != OK ) /* Ran out of files, or error */
{
RD_CurrentPath[0] = 0; /* Stop any repeat searches */
if ( res != OK ) { /* Ran out of files, or error */
*pOutNextOffset = -1;
}
else
{
if (RD_BufLen < 0) {
/* OK - was out of buffer space, force restart */
*pOutNextOffset = RD_ReqOffset;
//RD_CurOffset = 0;
//RD_CurrentPath[0] = 0;
}
else {
*pOutNextOffset = RD_ReqOffset;
}
}
*pOutNread = RD_ReqOffset-dir_offset;
*pOutNextOffset = con.resume_key;
*pOutNread = RD_CurCount;
if ( res == ENOMOREFILES )
return OK;
return res;
}
#if 0 /* Never called */
static err_t Func_ReadFreeSpace ( int sixtyfourbit, char *name, int *R )
{
_kernel_swi_regs r;
_kernel_oserror *err;
struct disk_size_response dsr;
r.r[0] = 2;
r.r[2] = (int) &dsr;
r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r);
if (err != NULL)
return ENOTPRESENT;
R[0] = dsr.freeblks;
if (sixtyfourbit) {
R[1] = R[4] = 0;
if (sixtyfourbit)
{
fspc_64 dsr[3];
r.r[0] = 4;
r.r[2] = (int) &dsr;
r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r);
if (err != NULL)
return ENOTPRESENT;
R[0] = dsr[1].lo;
R[1] = dsr[1].hi;
R[2] = 0x7FFFFFFF;
R[3] = dsr.totalblks;
R[3] = dsr[0].lo;
R[4] = dsr[0].hi;
}
else {
else
{
struct disk_size_response dsr;
r.r[0] = 2;
r.r[2] = (int) &dsr;
r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r);
if (err != NULL)
return ENOTPRESENT;
R[0] = dsr.freeblks;
R[1] = 0x7FFFFFFF;
R[2] = dsr.totalblks;
}
return OK;
}
#endif
/* Func ============================================================= */
_kernel_oserror *fsentry_func ( int *R )
{
err_t err;
bool flushnames = false;
debug1("FS_func(%d)", R[0] );
......@@ -423,8 +382,10 @@ _kernel_oserror *fsentry_func ( int *R )
}
}
#endif
if ( err == OK )
if ( err == OK ) {
err = SMB_Rename ( DOSnamebuf, DOSnamebuf+DOS_NAME_LEN );
flushnames = true;
}
#ifdef LONGNAMES
if (SMB_IsLongNameFS(DOSnamebuf + DOS_NAME_LEN)) {
......@@ -476,40 +437,29 @@ _kernel_oserror *fsentry_func ( int *R )
case FSEntry_Func_Reason_BootFilingSystem:
LM_Boot();
err = OK;
flushnames = true;
break;
case FSEntry_Func_Reason_ShutDown:
/* On shutdown, disconnect all drives */
err = SMB_Shutdown();
break;
/* On shutdown, disconnect all drives */
err = SMB_Shutdown();
flushnames = true;
break;
case FSEntry_Func_Reason_ReadDirectoryEntries:
case FSEntry_Func_Reason_ReadDirectoriesAndInformation:
case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation:
err = Func_ReadDir ( R[0], name_R(1), name_R(2),
R[3], R[4], R[5], &R[3], &R[4] );
break;
case FSEntry_Func_Reason_ResolveWildcard:
/* Tell FileSwitch to do it itself */
R[4] = -1;
err = OK;
break;
case FSEntry_Func_Reason_ReadFreeSpace:
err = Func_ReadFreeSpace ( 0, name_R(1), R );
break;
case FSEntry_Func_Reason_ReadFreeSpace64:
err = Func_ReadFreeSpace ( 1, name_R(1), R );
break;
default:
err = EBADPARAM;
break;
}
#ifdef LONGNAMES
NameCache_Flush(ncf_FSFUNC_EXIT);
if (flushnames) NameCache_Flush(ncf_FSFUNC_EXIT);
#endif
return Xlt_Error(err);
......@@ -542,6 +492,7 @@ _kernel_oserror *fsentry_file( int *R )
int tmp;
DOS_ATTRIBS da;
RISCOS_ATTRIBS ra;
bool flushnames = false;
debug1("FS_file(%d)", R[0] );
......@@ -570,6 +521,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.execaddr = R[3];
ra.flags = ROA_READ | ROA_WRITE;
Xlt_CnvROtoDOS(&ra, &da, CNV_DATETIME | CNV_ATTRIBS );
flushnames = true;
#ifdef LONGNAMES
strncpy(DOSnamebuf + DOS_NAME_LEN, DOSnamebuf, DOS_NAME_LEN);
if (Xlt_AddROType(DOSnamebuf, ra.loadaddr)) {
......@@ -637,6 +589,7 @@ _kernel_oserror *fsentry_file( int *R )
break;
}
flushnames = true;
if ( R[0] == FSEntry_File_Reason_WriteLoadAddress )
{
ra.loadaddr = R[2];
......@@ -675,6 +628,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.loadaddr = R[2];
ra.execaddr = R[3];
ra.flags = R[5];
flushnames = true;
#ifdef LONGNAMES
{
......@@ -706,6 +660,7 @@ _kernel_oserror *fsentry_file( int *R )
R[3] = ra.execaddr;
R[4] = da.length;
R[5] = ra.flags;
flushnames = true;
if ( da.attr & ATTR_DIR )
{
......@@ -725,8 +680,9 @@ _kernel_oserror *fsentry_file( int *R )
break;
case FSEntry_File_Reason_CreateDirectory:
Xlt_CnvRenameX2 ( DOSnamebuf, DOSnamebuf );
err = SMB_MkDir ( DOSnamebuf );
Xlt_CnvRenameX2 ( DOSnamebuf, DOSnamebuf );
err = SMB_MkDir ( DOSnamebuf );
flushnames = true;
break;
/* Read information calls ---------------------------- */
......@@ -759,7 +715,7 @@ _kernel_oserror *fsentry_file( int *R )
}
#ifdef LONGNAMES
NameCache_Flush(ncf_FSFILE_EXIT);
if (flushnames) NameCache_Flush(ncf_FSFILE_EXIT);
#endif
return Xlt_Error(err);
......@@ -1058,6 +1014,7 @@ bool FS_Init(void)
for ( i=0; i<MAXFILES; i++ )
FileTbl[i].Free = true;
NextHandle = 0;
return true;
}
......@@ -43,7 +43,7 @@
#include "netbios.h"
#include "SMB.h"
#include "xlate.h"
#include "version.h"
#include "VersionNum"
#include "omni.h"
#include "printers.h"
#include "RPC.h"
......@@ -92,13 +92,6 @@ struct NETBIOS_TRANSPORT *NB_ActiveTransport; /* Selected net transport */
static pfnTransportInit NB_InitedTransport; /* Identify active transport */
static bool LM_Declared; /* True if we're registered as a filing system */
/* ------------------------------- */
char Default_FileTName[6];
int Default_FileType;
/* ------------------------------- */
#define CMOS_FSNUMBER 5
......@@ -340,21 +333,6 @@ static _kernel_oserror *Cmd_LanMan ( const char *args )
/* --------------------- */
#if 0
static char *(LM_local_num)(char *buf)
{
char *sep, *map, *space = buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 1, &sep)) return buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 2, &map)) return buf;
while (space && *sep) {
space = strchr(space, ' ');
if (space) *space = *sep;
}
return buf;
}
#endif
static _kernel_oserror *Cmd_Free ( const char *args )
{
_kernel_swi_regs r;
......@@ -376,18 +354,18 @@ static _kernel_oserror *Cmd_Free ( const char *args )
if (e == NULL) {
if (values[3] == 0 && values[5] == 0) {
printf("Bytes free &%08x\n", values[2] );
printf("Bytes free &%08X\n", values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x\n", values[4] );
printf("Bytes used &%08X\n", values[4] );
}
else {
printf("Bytes used unavailable\n");
}
}
else {
printf("Bytes free &%08x%08x\n", values[3], values[2] );
printf("Bytes free &%08X%08X\n", values[3], values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x%08x\n", values[5], values[4] );
printf("Bytes used &%08X%08X\n", values[5], values[4] );
}
else {
printf("Bytes used unavailable\n");
......@@ -478,12 +456,15 @@ static void SetDefaultVars ( void )
char fs_name [ FSERVER_LEN+1 ];
#ifdef DEBUG
LM_Vars.verbose = true; /* DEBUG NAS */
LM_Vars.verbose = true; /* DEBUG NAS */
#else
LM_Vars.verbose = false;
LM_Vars.verbose = false;
#endif
LM_Vars.initialised = LMInitState_Uninitialised;
LM_Vars.namemode = NM_FIRSTCAPS;
/* See where IP packets are going to be sent */
name = getenv("Inet$EtherType");
strcpyn ( LM_Vars.drivername,
(name==NULL) ? DEFAULT_ETHER_TYPE : name, NAME_LIMIT );
......@@ -500,10 +481,26 @@ static void SetDefaultVars ( void )
if ( name != NULL ) *name = 0;
}
/* Following 'get from CMOS' bits added 980127:RCE *
* to address user complain that it has to be typed in every time *
/* See if the user has overridden the default filetype */
name = getenv("LanMan$DefaultType");
if (name != NULL)
{
_swix(OS_FSControl, _INR(0,1)|_OUT(2), 31, name, &LM_Vars.default_type);
}
else
{
LM_Vars.default_type = CNV_DEFAULT_TYPE;
}
/* Read the base of the OS ROM so there's an address to use for
* untyped load/exec address, ensuring they would abort if used
*/
_swix(OS_Module, _INR(0,2)|_OUT(3), 12, 0, 0, &LM_Vars.untyped_address);
LM_Vars.untyped_address = LM_Vars.untyped_address & ~((1<<20) - 1);
/* Following 'get from CMOS' bits added 980127:RCE
* to address user complaints that it has to be typed in every time
*/
Lgn_Init();
GetFSName(fs_name);
if (fs_name[0] != '\0')
......@@ -511,20 +508,6 @@ static void SetDefaultVars ( void )
strcpy(LM_Vars.workgroup,fs_name);
}
LM_Vars.namemode = NM_FIRSTCAPS;
// load and convert default filetype to textual HEX
if(name = getenv(DefaultTypeEnvVar),name)
{
_swix(OS_FSControl,_INR(0,1)|_OUT(2),31,name,&Default_FileType);
}
else
{
Default_FileType=Default_File_Type_Number;
}
sprintf(Default_FileTName,",%03x",Default_FileType);
/* Set transport type from CMOS, unless overridden on command line */
#ifdef NO_NETBEUI
LanMan_InitTransport(NB_NBIP_Setup);
......@@ -564,7 +547,10 @@ static _kernel_oserror *Cmd_LMInfo ( const char *args )
(void) args;
Omni_Debug();
if (LM_Vars.verbose)
printf("Status: %s\n", LM_Status());
{
printf("Status: %s\n", LM_Status());
Stat_Show();
}
return NULL;
}
......@@ -641,15 +627,6 @@ static _kernel_oserror *Cmd_LMPrinters ( const char *args )
/* --------------------- */
static _kernel_oserror *Cmd_LMStats ( const char *args )
{
(void) args;
Stat_Show();
return NULL;
}
/* --------------------- */
static _kernel_oserror *Cmd_FS ( const char *args )
{
/* This is a *Configure/Status command handler - it's therefore unusual */
......@@ -792,7 +769,6 @@ static CommandFnPtr Cmd_Dispatch[] =
CmdEntry(LMLogoff),
CmdEntry(LMServer),
CmdEntry(LMPrinters),
CmdEntry(LMStats),
CmdEntry(FS),
CmdEntry(LMTransport),
CmdEntry(LMNameServer),
......@@ -936,7 +912,7 @@ static err_t ProcessCmdLine ( const char *_line )
case 'H':
case '?':
printf( "Lan Man client for RISCOS, version " VERSION_STRING
printf( "SMB client for RISCOS, version " Module_FullVersion
"\nWritten by Ian Harvey 1994-1996\nUse:\n"
"\t-dea0\tto use 'ea0' for network driver (etc)\n"
"\t-n\tto disable network browsing\n"
......@@ -1183,7 +1159,7 @@ static _kernel_oserror *LM_init_phase_2(void)
/*LM_StartupBoot();*/
if (want_boot) {
if (LM_Vars.verbose) printf("Booting ...\n");
if (LM_Vars.verbose) printf("Booting...\n");
LM_Boot();
}
......
......@@ -92,7 +92,7 @@
/* ---------------- */
struct status_resp /* Structure used to process STATUS_RESPOMSE */
struct status_resp /* Structure used to process STATUS_RESPONSE */
{
int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */
......@@ -273,8 +273,11 @@ EXPORT nametype_t _NB_DecodeName ( NETNAME *pnn, char *buf )
static uint NB_GetTime (void)
{
/* This is well-defined for RISCOS */
return * (uint *)0x10C;
uint tick;
/* Centisecond tick */
(void) _swix(OS_ReadMonotonicTime, _OUT(0), &tick);
return tick;
}
......@@ -1334,7 +1337,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
NBIP_CallbackFn_handler();
if (pNE->status == RMT_FOUND)
{
debug1("Name found at %lX\n", pNE->IPaddress.s_addr);
debug1("Name found at %X\n", pNE->IPaddress.s_addr);
return pNE;
}
}
......@@ -1358,7 +1361,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
pNE->TTL_StartTime = NB_GetTime();
pNE->TTL_Interval = 1; /* Doesn't last for long */
pNE->IPaddress = GetIPAddr ( (BYTE *) (pHE->h_addr_list[0]) );
debug1("Name found in hosts at %lX\n", pNE->IPaddress.s_addr);
debug1("Name found in hosts at %X\n", pNE->IPaddress.s_addr);
return pNE;
}
......@@ -1626,7 +1629,7 @@ static bool ReadData ( int sid, BYTE *where, int len, uint timeout, int flags )
if ( NB_GetTime() - tstart > timeout )
{
debug0("Timeout\n");
if ( timeout > 0) debug1("Timeout after %dcs\n", timeout);
return false;
}
}
......@@ -1641,7 +1644,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
struct sockaddr_in sa;
BYTE *p; uint len;
debug2("Attempting to connect - addr=%lXh, port %d\n",
debug2("Attempting to connect - addr=%Xh, port %d\n",
pNS->rmt_addr.sin_addr.s_addr, ntohs(pNS->rmt_addr.sin_port) );
/* Entered with pNS->sid = a socket descriptor, and pNS->rmt_addr is
......@@ -1698,7 +1701,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
return EDATALEN;
pNS->rmt_addr.sin_addr = GetIPAddr( DatagramBuf );
pNS->rmt_addr.sin_port = htons(GetShort( DatagramBuf+4 ));
debug2("Retargeted to %lXh, port %d\n",
debug2("Retargeted to %Xh, port %d\n",
pNS->rmt_addr.sin_addr.s_addr, ntohs(pNS->rmt_addr.sin_port) );
return ERETARGET;
}
......
......@@ -102,18 +102,17 @@ static void NameCache_Exit(void)
{
free(NameCache.data);
NameCache.data = NULL;
debug1("NameCache hits: %d\n", NameCache.hits);
}
void NameCache_Flush(ncf_reason why)
{
debug1("NameCacheFlush(reason = %d)\n", why);
debug2("NameCacheFlush(reason = %d) hits %d\n", why, NameCache.hits);
if (why == ncf_REINIT) NameCache.hits = 0;
if (NameCache.data) {
NameCache.head = 0;
NameCache.tail = 0;
NameCache.last = -1;
((rec_hdr *) NameCache.data) -> offset_next = -1;
NameCache.head = 0;
NameCache.tail = 0;
NameCache.last = -1;
((rec_hdr *) NameCache.data) -> offset_next = -1;
}
}
......
......@@ -85,7 +85,7 @@
/* ---------------- */
struct status_resp /* Structure used to process STATUS_RESPOMSE */
struct status_resp /* Structure used to process STATUS_RESPONSE */
{
int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */
......
This diff is collapsed.
This diff is collapsed.
......@@ -28,16 +28,14 @@
#include <stdlib.h>
#include <ctype.h>
#include "kernel.h"
#include "stdtypes.h"
#include "swis.h"
#include "Xlate.h"
#include "attr.h"
#include "omni.h"
#include "LanMan.h"
#include "lmvars.h"
#include "SMB.h"
#include "Transact.h"
#include "NameCache.h"
#ifdef LONGNAMES
......@@ -50,13 +48,6 @@
*/
static const int deaddead = (int)0xDEADDEAD;
/* For the moment, untyped files have these invented load/exec addresses.
* They ensure that if such a file is *Load'ed or *Run'ed, then a data
* abort will occur
*/
static const int untyped_load = 0x03800000;
static const int untyped_exec = 0x03800000;
/* Macro returns non-zero if the specifiec load addressis indicative of
* a filetyped object. Rather than checking for the top 12 bits being
* set, it's much quicker to arithmetic shift it right 20 bits and test
......@@ -75,8 +66,7 @@ static const int untyped_exec = 0x03800000;
* ORR rn, rn, #0x0FF00000: MOV load,load,LSL #12:
* EOR load, type, load LSR #20: EOR load,rn,load LSL #8
*/
#define ENCODE_FILETYPE(load,type) \
(((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
#define ENCODE_FILETYPE(load,type) (((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
#endif
......@@ -102,18 +92,18 @@ static const int untyped_exec = 0x03800000;
*/
int stricmp(const char *first, const char *second)
{
for (;;) {
unsigned int a = *first++;
unsigned int b = *second++;
if (a == 0) return -b;
if (a != b) {
unsigned int c = (unsigned int) tolower(a);
unsigned int d = (unsigned int) tolower(b);
signed int result = c - d;
if (result != 0) return result;
}
}
for (;;) {
unsigned int a = *first++;
unsigned int b = *second++;
if (a == 0) return -b;
if (a != b) {
unsigned int c = (unsigned int) tolower(a);
unsigned int d = (unsigned int) tolower(b);
signed int result = c - d;
if (result != 0) return result;
}
}
}
/* strcpyn(): copies a string with given max length. Note that
......@@ -157,7 +147,7 @@ void strcpyn_lower ( char *d, const char *s, int len )
/* -------------------------- */
static int daycount[13] =
static const ushort daycount[13] =
{
0,
0, /* Jan=31 */
......@@ -245,7 +235,7 @@ void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pDA, RISCOS_ATTRIBS *pRA, int flags )
/* Total = (thi << 16)+tlo; */
pRA->loadaddr = 0xFFF00000 + ( (thi+ (tlo >> 16) ) >> 16) +
(Default_FileType << 8); /* Default type = 'Text' */
(LM_Vars.default_type << 8); /* Default type */
pRA->execaddr = (thi << 16) + tlo;
}
......@@ -376,27 +366,15 @@ static char Xlt_DefaultDrv = 'A';
#define CH_WILD 2
#define CH_PATH 3
#define CH_SEP 4
#define CH_DUD '_'
/* Current tables set
DOS RISCOS
# ?
$ <
% >
& +
@ =
^ ,
Illegal in RISCOS names: space * " : \ | # $ % & @ ^ DLE
Also: RISCOS { and [ map to DOS (, } and ] to ),
; and top-bit-set chars to _
/*
Illegal in DOS names: / < > ? + , ; = [ ] : * \ " | DEL
Illegal in RISCOS names: . $ % # & ^ @ : * \ " | DEL
All control characters and space are bad
All top bit set characters are swapped for _
*/
static char xlt_RO2DOS[256] =
{
CH_END, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, /* 00-07 */
......@@ -417,7 +395,7 @@ static char xlt_RO2DOS[256] =
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '(', CH_ERR, ')', '~', CH_ERR,
'X', 'Y', 'Z', '{', CH_ERR, '}', '~', CH_ERR,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
......@@ -440,6 +418,48 @@ static char xlt_RO2DOS[256] =
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
static char xlt_DOS2RO[256] =
{
CH_END, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, /* 08-1F */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 10-17 */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 17-1F */
CH_DUD, '!', CH_DUD, '?', '<', '>', '+', '\'',
'(', ')', CH_DUD, '+', ',', '-', CH_SEP, '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', CH_DUD, ';', '<', '=', '>', '?',
'=', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', CH_DUD, ']', ',', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', CH_DUD, '}', '~', CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
static err_t nameROtoDOS ( char *dst, char *src )
{
......@@ -510,50 +530,6 @@ static err_t nameROtoDOS ( char *dst, char *src )
}
/* -------------------------- */
static char xlt_DOS2RO[256] =
{
CH_END, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, /* 08-1F */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, '!', CH_DUD, '?', '<', '>', '+', '\'',
'(', ')', CH_DUD, '+', ',', '-', CH_SEP, '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', CH_DUD, ';', '<', '=', '>', '?',
'=', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', CH_DUD, ']', ',', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', CH_DUD, '}', '~', CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
/* -------------------------- */
......@@ -561,7 +537,7 @@ static char xlt_DOS2RO[256] =
void Xlt_NameDOStoRO ( char *dst, char *src )
{
int i, c;
int lcl_name_mode = LM_Vars.namemode & 3;
int lcl_name_mode = LM_Vars.namemode & (NM_LOWERCASE | NM_FIRSTCAPS | NM_PRESERVED);
for ( i=0; i<12; i++ ) /* Up to 12 chars in 8.3 name */
{
......@@ -754,22 +730,18 @@ static char Xlt_ContentiousCharCheck(char e, char d)
* and that structure is updated with the real filename once a match
* has been found. The format parameter should always be 1.
*/
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst )
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, bool *taken, void *_dst )
{
Xlt_NXCX2_Data *dst = _dst;
char *eptr = (char *) (entry + 23);
char *dptr = 1 + strrchr(dst->matchbuf, '\\');
err_t res = OK;
*taken = true;
if (dst->dstcpy[0] != '*') {
return EOUTOFMEM;
}
debug3("Xlt_NameXlateCallbackX2: checking `%s', against `%s' in `%s'\n",
(char *) entry + 23,
dptr,
dst->dstcpybuf);
for (;;) {
char e = *eptr++;
char d = *dptr++;
......@@ -820,6 +792,7 @@ static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst )
static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
{
static Xlt_NXCX2_Data private;
static Transact_SearchContext con;
char *inptr;
err_t status;
......@@ -835,7 +808,9 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
* private.dstcpy must point at the * character so that the callback
* function can write the matched target name straight in
*/
#if 0 /* No side effects */
(void) NameCache_Locate(private.matchbuf);
#endif
strcpy(private.dstcpybuf, private.matchbuf);
private.dstcpy = strrchr(private.dstcpybuf, '\\');
if (private.dstcpy) {
......@@ -905,24 +880,27 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
/* Repeatedly search the directory until we find a match, or there are
* no more entries to be read back
*/
con.resume_key = 0;
for (status = OK, inptr = private.dstcpybuf; status == OK; inptr = NULL) {
status = SMB_ReadDirEntries(inptr, 32, Xlt_NameXlateCallbackX2,
&private, NULL);
&private, &con);
switch (status) {
case OK:
/* More entries to read, and no match found yet */
break;
case EOUTOFMEM:
/* Found it */
strcpy(dst, private.dstcpybuf);
debug1("\n**RIGHT. Got a match: `%s'\n", dst);
debug1("**RIGHT. Got a match: `%s'\n", dst);
break;
default:
/* Definitely didn't find it - revert to original filename
* or at least filename with nasties resolved as far as possible
*/
strcpy(dst, private.matchbuf);
debug1("\n**WRONG. Not got a match. Reverting to `%s'\n", dst);
debug1("**WRONG. Not got a match. Reverting to `%s'\n", dst);
break;
}
}
......@@ -935,7 +913,7 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
*/
static err_t Xlt_NameROtoDOSX2 ( char *dst, char *src )
{
return Xlt_NameROtoDOSX2_sub(dst, src, 0);
return Xlt_NameROtoDOSX2_sub(dst, src, 0);
}
#endif
......@@ -1213,8 +1191,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (stricmp(leafname+1, FileString_UntypedFile) == 0)
{
debug0("File is untyped (,lxa)\n");
pRA->loadaddr = untyped_load;
pRA->execaddr = untyped_exec;
pRA->loadaddr = LM_Vars.untyped_address;
pRA->execaddr = LM_Vars.untyped_address;
*terminator = leafname;
res = OK;
}
......@@ -1282,8 +1260,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (res != OK)
{
/* No ",ttt" and no mimemap lookup - mark as a Text file */
pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, Default_FileType);
/* No ",ttt" and no mimemap lookup - mark as default type */
pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, LM_Vars.default_type);
}
return res;
......@@ -1294,36 +1272,30 @@ return res;
#ifdef LONGNAMES
/* Copies the filetype information from one name to another.
* Note that the file saving routine actually uses this
* routine to strip filetype information by passing both
* parameters the same. This must continue to function.
* JB 18/12/2003 .. make sure the ,xxx is only removed IF
* both names are NOT (identical and contains .xxx)
* (function only seen in file renaming so far JB)
* Called by "rename object" and "create directory", note
* thie routine can be called with src and dst the same
* to simply remove an extension. This must continue to function.
*/
err_t Xlt_CnvRenameX2 ( char *src, char *dst )
{
RISCOS_ATTRIBS RA;
char *nterm; // *terminator
int cnvq=strcmp(src,dst); // check if just need to strip..
// if src and dst are same, check if it should have the ,xxx appended
// if so, ensure it still is...
// if(!cnvq) // just strip...
// {
// if((strlen(dst)>4) && (dst[strlen(dst)-4] == ',')) cnvq++;
// }
if (Xlt_SplitLeafnameX2 ( dst, &RA, &nterm ) != OK) {
char *terminator, *nterm;
int cnvq = strcmp( src, dst );
if (Xlt_SplitLeafnameX2( dst, &RA, &nterm ) != OK) {
/* No type information - find end of string */
nterm = strchr(dst, '\0');
}
else {
/* Strip old type information in case source didn't have any either */
/* Strip destination's type information in case source didn't have any either */
*nterm = '\0';
}
Xlt_SplitLeafnameX2 ( src, &RA, &nterm ) ; // recover source's filetype
// if not identical strings.. add type if not in dos name
if (cnvq)Xlt_AddROType (dst,RA.loadaddr);
if (Xlt_SplitLeafnameX2( src, &RA, &terminator ) && cnvq) {
/* If dst and src names truly differ apply src's type to dst */
Xlt_AddROType(dst, RA.loadaddr);
}
return OK;
}
#endif
......@@ -1332,7 +1304,7 @@ err_t Xlt_CnvRenameX2 ( char *src, char *dst )
#ifdef LONGNAMES
/* Adds the type suffix for a RISC OS filename. The type is extracted
* from the passed load address. unless DOS name is sufficient
* from the passed load address, unless DOS name is sufficient
*/
int Xlt_AddROType ( char *leafname, uint loadaddr )
{
......@@ -1353,7 +1325,7 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
sprintf(typebuf+1, "%03x", type);
}
// strip any acorn filetype suffix
/* Strip any acorn filetype suffix */
if (Xlt_SplitLeafnameX2 ( leafname, &RA, &nterm ) != OK) {
/* No type information - find end of string */
nterm = strchr(leafname, '\0');
......@@ -1362,28 +1334,27 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
/* Strip old type information in case source didn't have any either */
*nterm = '\0';
}
// check leaf for dos file type, else add acorn extra...
if (leafname[1] == ':')
{
/* Check leaf for DOS file type, else add acorn extra... */
if (leafname[1] == ':') {
term = strrchr(leafname, '.'); /* strrchr catches names like "file.tar.gz" */
}
else
{
else {
term = strrchr(leafname, '/'); /* strrchr catches names like "file/tar/gz" */
}
if(term)
{ // found a DOS type
if(!_swix(MimeMap_Translate,_INR(0,2)|_OUT(3), // so check the mimemap
MMM_TYPE_DOT_EXTN,term,
MMM_TYPE_RISCOS,&ftype))
{ // got a name valid in RISCOS
sprintf(ftypebuf,",%03x",ftype);
if(!strcmp(typebuf,ftypebuf)) return 1; // its OK.. no need to append type
if (term) {
/* Found a DOS type so check the mimemap */
if (!_swix(MimeMap_Translate, _INR(0,2)|_OUT(3),
MMM_TYPE_DOT_EXTN, term,
MMM_TYPE_RISCOS, &ftype)) {
/* Got a name valid in RISCOS */
sprintf(ftypebuf, ",%03x", ftype);
if (!strcmp(typebuf, ftypebuf)) return 1;
}
}
// Don't append ,xxx filetype if its the default
if(strcmp(typebuf,Default_FileTName))strcat(leafname, typebuf);
/* Don't append ,xxx filetype if its the default */
sprintf(ftypebuf,",%03x",LM_Vars.default_type);
if (strcmp(typebuf,ftypebuf)) strcat(leafname, typebuf);
return 1;
}
#endif
......
......@@ -102,7 +102,7 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMLogoff\r" ),
LMServer(min-args:1, max-args:17,
help-text: "*LMserver adds a server name and list of shared drives\r"
help-text: "*LMServer adds a server name and list of shared drives\r"
"Syntax:\t*LMServer server [sharename] [sharename] ...",
fs-command:,
invalid-syntax: "Syntax:\t*LMServer server [sharename] [sharename] ...\r", ),
......@@ -114,13 +114,6 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMPrinters server [printername] [printername] ...\r",
),
LMStats(min-args:0, max-args:0,
help-text: "*LMStats shows network statistics\r"
"Syntax:\t*LMStats",
fs-command:,
invalid-syntax: "Syntax:\t*LMStats",
),
FS(min-args:0, max-args:1,
help-text: "*Configure FS <name> sets the file server or domain name from "
"which LanManFS will attempt to boot\rSyntax:\t*Configure FS file-server-name",
......@@ -153,7 +146,7 @@ command-keyword-table: LM_Command
ListFS(min-args:0, max-args:1,
help-text: "*ListFS displays the servers in the current LAN workgroup or\r"
"the shares on the given server",
"the shares on the given server\rSyntax:\t*ListFS [server]",
fs-command:,
invalid-syntax: "Syntax:\t*ListFS [server]\r",
)
......
Replaced peek of 0x10C in OS workspace with call to SWI OS_MonotonicTime.
Removed a hardcoded 0x03800000 address, now calls SWI OS_Module.
Deleted "h.version" - no longer used (VersionNum included directly).
Added "smb_search.txt" to docs as it doesn't seem to be in recent CIFS specs
but we still use it.
Bizarre system variable LMDefaultType renamed to LanMan$DefaultType to match
the other similar variable names. Globals moved into LM_Vars structure.
Documentation of supported system variables:
LanMan$ScopeID <string> Sets the optional NetBIOS scope id
LanMan$NameServer <ip-addr> Sets the address of the name server
to use
LanMan$DefaultType <filetype-string> Sets a default filetype to use, when
reading an SMB share and no filetype
can be deduced this will be used, when
writing no ",xxx" extension will be
used for this type either
Replaced TIFF in the built in filetype table with JPEG, removed ARC. This
means the table now contains things that can be opened with the ROM apps only.
Removed debugging LMStats command (the stats now appear in LMInfo)
Function OmniS_FastMultiply64 was pushing LR to use as a scratch register (as
was macro FunctionEntry) with no corresponding pull. As macro Return happens
to pull LR the return address was valid but left a word on the stack for
every call to Free. This resulted in free (being the first value printed)
being correct but used and total space wildly incorrect: a 1132 terabyte
drive in my case.
Removed
FSEntry_Func_Reason_ResolveWildcard
FSEntry_Func_Reason_ReadFreeSpace
FSEntry_Func_Reason_ReadFreeSpace64
since these are only called if the FS supports image file extensions, which
LanManFS doesn't.
Minor tweaks
Marked a few tables as const, corrected some spelling mistakes.
%lx formatters changed to %x to remove a few compiler warnings.
Changed spelling of "Disk" to "Disc".
Added syntax description for ListFS to explain optional [server] parameter.
Changed print formatter for *FREE to match that of FileCore.
!MkDebug switch renamed so it assembles "s.Interface" correctly.
Rewrote directory finding routines (SMB_ReadDirEntries and its callers) as
it dealt poorly with reentrancy. This was highlighted by a desktop count
of a complex directory tree such as C:\Windows\System32 where it would
inexplicably stop part way through (on the test WinXP system about 2000 files
in) and some duff SMB responses coughed up onto the network.
This was caused by the resume value being associated with a specific
directory handle (but not being able to return both since OS_GBPB only allows
a 32 bit context to be returned in R4).
When desktop count recursed into a deeper level the top level find query
was closed, then when returning to the top level desktop count correctly
carried on from the last R4 context it had but the search went off in the
deeper (still open) find query. eg.
:
\Windows\System32 [say 1000 files total]
:
[500 normal files here]
:
\Windows\System32\SmallDir [say only 10 files]
:
[try to continue at position 502, but request it from 'SmallDir']
:
It was also mind meltingly complicated for no apparent reason.
The short filename version has been correspondingly updated, so they both now
count the same number of files. Because the short name version has a 21 byte
directory context to return in R4 a simple hash of this is used, on future
calls the search will use the last cached 21 byte context only if the
directory hasn't changed AND the context is valid AND the hash matches -
otherwise a manual search for the hash is made (which may be a bit slow but
hopefully infrequent).
Short directory find tested by setting MAX_DIALECT to 0 temporarily.
The short filenames version of Att_GetInfo was rudely stomping on the load
address, now it AND's and OR's only the nybbles it is responsible for.
Modified the short filename character translation table to allow "{}" since
these are valid in both DOS and RISC OS, whereas before they had an
asymmetrical mapping.
SMB: search
This command is used to search directories.
Client Request Description
================================== =================================
UCHAR WordCount; Count of parameter words = 2
USHORT MaxCount; Number of dir. entries to return
USHORT SearchAttributes;
USHORT ByteCount; Count of data bytes; min = 5
UCHAR BufferFormat1; 0x04 -- ASCII
UCHAR FileName[]; File name, may be null
UCHAR BufferFormat2; 0x05 -- Variable block
USHORT ResumeKeyLength; Length of resume key, may be 0
UCHAR ResumeKey[]; Resume key
FileName specifies the file to be sought. SearchAttributes indicates
the attributes that the file must have, and is described in the "File
Attribute Encoding" section of this document. If SearchAttributes is
zero then only normal files are returned. If the system file, hidden or
directory attributes are specified then the search is inclusive@both the
specified type(s) of files and normal files are returned. If the volume
label attribute is specified then the search is exclusive, and only the
volume label entry is returned.
MaxCount specifies the number of directory entries to be returned.
Server Response Description
================================== =================================
UCHAR WordCount; Count of parameter words = 1
USHORT Count; Number of entries returned
USHORT ByteCount; Count of data bytes; min = 3
UCHAR BufferFormat; 0x05 -- Variable block
USHORT DataLength; Length of data
UCHAR DirectoryInformationData[]; Data
The response will contain one or more directory entries as determined by
the Count field. No more than MaxCount entries will be returned. Only
entries that match the sought FileName and SearchAttributes combination
will be returned.
ResumeKey must be null (length = 0) on the initial search request.
Subsequent search requests intended to continue a search must contain
the ResumeKey field extracted from the last directory entry of the
previous response. ResumeKey is self-contained, for on calls containing
a non-zero ResumeKey neither the SearchAttributes or FileName fields
will be valid in the request. ResumeKey has the following format:
Resume Key Field Description
================================== =================================
UCHAR Reserved; bit 7 - consumer use
bits 5,6 - system use (must
preserve)
bits 0-4 - server use (must
preserve)
UCHAR FileName[11]; Name of the returned file
UCHAR ReservedForServer[5]; Client must not modify
UCHAR ReservedForConsumer[4]; Server must not modify
FileName is 8.3 format, with the three character extension left
justified into FileName[9-11]. If the client is prior to the LANMAN1.0
dialect, the returned FileName should be uppercased.
SMB_COM_SEARCH terminates when either the requested maximum number of
entries that match the named file are found, or the end of directory is
reached without the maximum number of matches being found. A response
containing no entries indicates that no matching entries were found
between the starting point of the search and the end of directory.
There may be multiple matching entries in response to a single request
as SMB_COM_SEARCH supports wildcards in the last component of FileName
of the initial request.
Returned directory entries in the DirectoryInformationData field of the
response each have the following format:
Directory Information Field Description
================================== =================================
SMB_RESUME_KEY ResumeKey; 00..20 Described above
UCHAR FileAttributes; 21 Attributes of the found file
SMB_TIME LastWriteTime; 22..23 Time file was last written
SMB_DATE LastWriteDate; 24..25 Date file was last written
ULONG FileSize; 26..29 Size of the file
UCHAR FileName[13]; 30..42 ASCII, space-filled null
terminated
FileName must conform to 8.3 rules, and is padded after the extension
with 0x20 characters if necessary. If the client has negotiated a
dialect prior to the LANMAN1.0 dialect, or if bit0 of the Flags2 SMB
header field of the request is clear, the returned FileName should be
uppercased.
As can be seen from the above structure, SMB_COM_SEARCH can not return
long filenames, and can not return UNICODE filenames. Files which have
a size greater than 2^32 bytes should have the least significant 32 bits
of their size returned in FileSize.
......@@ -33,6 +33,8 @@ struct LMvars
char *password_ptr; /* Default password e.g. none */
bool verbose;
int initialised; /* Initialisation state */
int default_type; /* Type for which no ",xxx" suffix will be added */
int untyped_address; /* Base of the OS ROM */
};
extern struct LMvars LM_Vars;
......@@ -27,13 +27,6 @@
#define FilingSystemName "LanMan"
#define Our_FS_Number 102
/* Default map filetype when file on server has no type info */
#define Default_File_Type_Number FileType_Text
/* Env Variable to contain replacement default type */
#define DefaultTypeEnvVar "LMDefaultType"
#define FSControl_AddFilingSystem 12
#define FSControl_SelectFilingSystem 14
#define FSControl_RemoveFilingSystem 16
......
......@@ -42,7 +42,6 @@ extern void Omni_StartUp ( void );
extern void Omni_Shutdown ( void );
extern void Omni_ClearLists ( void );
extern bool Omni_Registered;
extern void Omni_ServiceCall ( _kernel_swi_regs *R );
extern void Omni_RecheckInfo ( int flags );
......
......@@ -23,7 +23,7 @@
#define DIRENTRY_SIZE 22
typedef err_t (*ENUM_DIR_FN) ( BYTE *entry, int format, void *private );
typedef err_t (*ENUM_DIR_FN) ( BYTE *entry, int format, bool *taken, void *private );
struct disk_size_response
{
......@@ -47,9 +47,6 @@ struct disk_size_response
#define MAX_SETUPWORDS (4)
#endif
typedef union Transact_SearchContext Transact_SearchContext;
struct TransactParms
{
int parms_in_len;
......@@ -84,12 +81,7 @@ struct TransactParms
# define sizeof_TransactParms_external (sizeof(struct TransactParms))
#endif
/* Exported routines ================ */
/* Directory functions */
extern err_t SMB_MkDir ( char *path );
extern err_t SMB_RmDir ( char *path );
extern err_t SMB_Delete ( char *path );
......@@ -97,12 +89,11 @@ extern err_t SMB_Rename ( char *oldpath, char *newpath );
extern err_t SMB_GetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_SetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_ReadDirEntries ( char *path, int max_count,
ENUM_DIR_FN dirfn, void *private, Transact_SearchContext *);
ENUM_DIR_FN dirfn, void *private, void *context);
extern err_t SMB_GetFreeSpace ( char lettr, struct disk_size_response
* pDSR );
/* File functions */
extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr,
int *pOutFH );
......@@ -120,19 +111,15 @@ extern err_t SMB_Flush ( int fh ) ;
extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr );
/* Printer functions */
extern err_t SMB_OpenPrinter ( char drvlettr, char *printid, int *ph_out );
extern err_t SMB_WritePrinter ( int PH, BYTE *data, int datalen );
extern err_t SMB_ClosePrinter ( int PH );
/* Transaction (RPC) functions */
extern err_t SMB_Transact ( char drvlettr, char *trans_name,
struct TransactParms *pT );
/* Connect/disconnect functions ----------------------- */
/* Connect/disconnect functions */
extern err_t SMB_CreateShare ( int service_type,
int style,
char *serv_name, char *drv_name,
......@@ -234,16 +221,16 @@ extern err_t SMB_Shutdown ( void );
(i) Its contents may become corrupted across any SMB_xxxx calls.
The main exception is the SMB_Transact call: this buffer is
intended for use as the return parameter/data buffer.
intended for use as the return parameter/data buffer.
(ii) It must not be used by anything which may be called during
an SMB call (transmit/receive processing functions, timer
callbacks, SMB_EnumerateDir callbacks etc). This probably
means anything in Network, LLC, and NetBIOS.
an SMB call (transmit/receive processing functions, timer
callbacks, SMB_EnumerateDir callbacks etc). This probably
means anything in Network, LLC, and NetBIOS.
(iii) Any other module (=C source file) may use it freely. In
general, it should be assumed corrupted across calls
between modules.
(iii) Any other C source file may use it freely. In
general, it should be assumed corrupted across calls
between modules.
*/
#ifdef LONGNAMES
/* Need a much larger buffer */
......
......@@ -20,26 +20,22 @@
*
*/
#define SEARCH_ST_SIZE 21
typedef struct ActiveShare *hSHARE;
union Transact_SearchContext {
struct Transact1_SearchContext {
bool NextSearchOK;
BYTE SearchState[SEARCH_ST_SIZE];
hSHARE SearchDrive;
} t1;
struct Transact2_SearchContext {
struct Transact1_SearchContext t1;
struct TransactParms tp;
DWORD resume_key;
WORD dir_handle;
bool dir_handle_valid;
char last_filename[DOS_NAME_LEN];
} t2;
};
#define SEARCH_ST_SIZE 21
typedef struct {
/* Common state */
hSHARE search_drive;
struct TransactParms tp;
char dir_path[DOS_NAME_LEN];
DWORD resume_key;
bool resume_key_encountered;
WORD dir_handle;
bool dir_handle_valid;
/* Cached state for short names */
BYTE resume_state[SEARCH_ST_SIZE];
} Transact_SearchContext;
extern void Transact_addword(struct TransactParms *TP, int value);
extern void Transact_addlong(struct TransactParms *TP, long value);
......
......@@ -31,9 +31,9 @@ extern void strcpyn_lower ( char *d, const char *s, int n );
extern void Xlt_Jumble ( char *str );
extern void Xlt_Unjumble ( char *str );
#define CNV_DATETIME 1
#define CNV_ATTRIBS 2
#define CNV_DEFAULT_TYPE FileType_Text
#define CNV_DATETIME 1
#define CNV_ATTRIBS 2
extern void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pInAttr,
RISCOS_ATTRIBS *pOutAttr, int flags );
......@@ -49,6 +49,8 @@ extern void Xlt_NameDOStoRO ( char *riscos_dst, char *dos_src );
#define NM_PRESERVED 0
#define NM_LOWERCASE 1
#define NM_FIRSTCAPS 2
#define NM_INTERNAL 4 /* Can't be selected at the CLI */
/* Mime mappings */
#define MimeMap_Translate 0x50B00
......