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 @@ ...@@ -14,4 +14,4 @@
| |
Dir <Obey$Dir> Dir <Obey$Dir>
wimpslot 4000k 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. * 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_MinorVersion_CMHG
#define Module_Date_CMHG 16 Feb 2004 #define Module_Date_CMHG 15 Apr 2009
#define Module_MajorVersion "2.30" #define Module_MajorVersion "2.32"
#define Module_Version 230 #define Module_Version 232
#define Module_MinorVersion "" #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_ComponentName "LanManFS"
#define Module_ComponentPath "RiscOS/Sources/Networking/Omni/Protocols/LanManFS" #define Module_ComponentPath "RiscOS/Sources/Networking/Omni/Protocols/LanManFS"
#define Module_FullVersion "2.30" #define Module_FullVersion "2.32"
#define Module_HelpVersion "2.30 (16 Feb 2004)" #define Module_HelpVersion "2.32 (15 Apr 2009)"
#define Module_LibraryVersionInfo "2:30" #define Module_LibraryVersionInfo "2:32"
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "xlate.h" #include "xlate.h"
#include "omni.h" #include "omni.h"
#include "LanMan.h" #include "LanMan.h"
#include "LMVars.h"
/* "Default" filetype logic ------------------------------------- */ /* "Default" filetype logic ------------------------------------- */
...@@ -54,14 +55,13 @@ struct ext_type ...@@ -54,14 +55,13 @@ struct ext_type
int type; int type;
}; };
static struct ext_type FTypes[] = static const struct ext_type FTypes[] =
{ {
{ "TXT", 0xFFF }, /* Text */ { "TXT", 0xFFF }, /* Text */
{ "C", 0xFFF }, { "C", 0xFFF },
{ "H", 0xFFF }, { "H", 0xFFF },
{ "ASM", 0xFFF }, { "ASM", 0xFFF },
{ "ARC", 0xDDC }, /* Spark */ { "JPG", 0xC85 }, /* JPEG */
{ "TIF", 0xFF0 }, /* TIFF File */
{ "PS", 0xFF5 }, /* Postscript */ { "PS", 0xFF5 }, /* Postscript */
{ NULL, 0 } { NULL, 0 }
}; };
...@@ -70,7 +70,7 @@ static struct ext_type FTypes[] = ...@@ -70,7 +70,7 @@ static struct ext_type FTypes[] =
static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra ) static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
{ {
struct ext_type *pET; const struct ext_type *pET;
int ftype; int ftype;
_kernel_swi_regs rset ; _kernel_swi_regs rset ;
...@@ -86,11 +86,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra ) ...@@ -86,11 +86,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
leafname = strchr(leafname, '.'); leafname = strchr(leafname, '.');
if ( leafname == NULL ) /* No extension */ if ( leafname == NULL ) /* No extension */
{ {
debug1("No suffix,assuming Text filetype for '%s'\n", leafname ); debug2("Assuming filetype %03x for '%s' due to no suffix\n", LM_Vars.default_type, leafname );
ra->loadaddr = Default_FileType << 8; ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
return; (LM_Vars.default_type << 8);
} return;
}
leafname++; /* Skip '.' */ leafname++; /* Skip '.' */
...@@ -99,11 +100,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra ) ...@@ -99,11 +100,12 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
rset.r[1] = (int)leafname; rset.r[1] = (int)leafname;
rset.r[2] = MMM_TYPE_RISCOS; rset.r[2] = MMM_TYPE_RISCOS;
if (_kernel_swi(MimeMap_Translate, &rset, &rset) == NULL) if (_kernel_swi(MimeMap_Translate, &rset, &rset) == NULL)
{ {
ra->loadaddr = rset.r[3] << 8; ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
debug2("Mimemap gave type %X for '%s'\n", rset.r[3], leafname ); (rset.r[3] << 8);
return; debug2("Mimemap gave type %X for '%s'\n", rset.r[3], leafname );
} return;
}
/* Look through the feable small table */ /* Look through the feable small table */
for ( pET = FTypes; pET->ext != NULL; pET++ ) for ( pET = FTypes; pET->ext != NULL; pET++ )
...@@ -111,7 +113,7 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra ) ...@@ -111,7 +113,7 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
if ( strcmp ( pET->ext, leafname ) == 0 ) if ( strcmp ( pET->ext, leafname ) == 0 )
{ {
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) | ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(pET->type << 8); (pET->type << 8);
return; return;
} }
} }
...@@ -365,7 +367,6 @@ err_t Attr_GetInfo ( char *filename, char *leafname, ...@@ -365,7 +367,6 @@ err_t Attr_GetInfo ( char *filename, char *leafname,
return Attr_GetInfoX2 ( filename, leafname, pRA ); return Attr_GetInfoX2 ( filename, leafname, pRA );
#endif #endif
if ( SetFileName(filename) != OK ) if ( SetFileName(filename) != OK )
return EBADNAME; return EBADNAME;
......
...@@ -39,53 +39,23 @@ ...@@ -39,53 +39,23 @@
#include "NameCache.h" #include "NameCache.h"
/* Some globals ================================== */
#define NAMEBUF_LEN (2*DOS_NAME_LEN) #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, static err_t FileGetAttribs ( char *filename, DOS_ATTRIBS *pda,
RISCOS_ATTRIBS *pra ); RISCOS_ATTRIBS *pra );
#define name_R(x) ((char *)R[x]) /* Read-directory subroutines ======================================= */
/* 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];
static int RD_Reason; static int RD_Reason;
static char *RD_BufPtr; static char *RD_BufPtr;
static int RD_BufLen; static int RD_BufLen;
static int RD_ReqCount; /* No. of entries required */ static int RD_ReqCount; /* No. of entries required */
static int RD_ReqOffset; /* Offset of currently required dir entry */ static int RD_CurCount; /* No. of entries given */
static int RD_CurOffset; /* Offset of next entry to be given to
Dir_CallbackFn */
/* ---------------- */
/* SNB: the blocks being written are those required by: /* Write one directory entry to the supplied buffer
* NAMES_ONLY => OS_GBPB 9 => (FSEntry_Func 14) * The directory entries can take one of three forms, taking up
* MOST_INFO => OS_GBPB 10 => (FSEntry_Func 15) * a variable degree of space
* ALL_INFO => OS_GBPB 11 => (FSEntry_Func 19)
*/ */
static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format ) 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 ) ...@@ -97,7 +67,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
int *IntPtr; int *IntPtr;
#ifndef LONGNAMES #ifndef LONGNAMES
(void) format; (void) format;
#else #else
if (format == 1) { if (format == 1) {
Xlt_ExpandSearchEntryX2(entry, DOSnamebuf, namebuf, &da, &ra); Xlt_ExpandSearchEntryX2(entry, DOSnamebuf, namebuf, &da, &ra);
...@@ -107,17 +77,18 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format ) ...@@ -107,17 +77,18 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
Xlt_ExpandSearchEntry(entry, DOSnamebuf, namebuf, &da, &ra); Xlt_ExpandSearchEntry(entry, DOSnamebuf, namebuf, &da, &ra);
name_len = strlen(namebuf) + 1; name_len = strlen(namebuf) + 1;
debug1("WriteEntry (%s)\n", namebuf);
switch ( reason ) switch ( reason )
{ {
case NAMES_ONLY: case FSEntry_Func_Reason_ReadDirectoryEntries:
rec_len = name_len; rec_len = name_len;
if (rec_len <= RD_BufLen) { if (rec_len <= RD_BufLen) {
memcpy(ptr, namebuf, name_len); memcpy(ptr, namebuf, name_len);
} }
break; break;
case MOST_INFO: case FSEntry_Func_Reason_ReadDirectoriesAndInformation:
rec_len = (20+name_len+3) & ~3; /* Round up to whole word */ rec_len = (20+name_len+3) & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) { if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr; IntPtr = (int *)ptr;
...@@ -130,7 +101,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format ) ...@@ -130,7 +101,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
} }
break; break;
case ALL_INFO: case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation:
rec_len = (29+name_len)+3 & ~3; /* Round up to whole word */ rec_len = (29+name_len)+3 & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) { if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr; IntPtr = (int *)ptr;
...@@ -151,10 +122,10 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format ) ...@@ -151,10 +122,10 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
} }
if (rec_len > RD_BufLen) { 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); rec_len, RD_BufLen);
RD_BufLen = -1; RD_BufLen = -1;
return NULL; return NULL;
} }
RD_BufLen -= rec_len; RD_BufLen -= rec_len;
...@@ -163,7 +134,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format ) ...@@ -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; (void) pw;
#ifdef LONGNAMES #ifdef LONGNAMES
...@@ -187,48 +158,49 @@ static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw ) ...@@ -187,48 +158,49 @@ static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
} }
} }
// debug3 ("Entry: current %d req %d count %d\n", *taken = false;
// RD_CurOffset, RD_ReqOffset, RD_ReqCount ); if ( RD_ReqCount > 0 )
if ( RD_ReqOffset == RD_CurOffset )
{ {
if ( RD_ReqCount > 0 ) char *w_result = WriteEntry ( RD_Reason, RD_BufPtr, entry, format );
{ if (w_result != NULL) {
char *w_result = WriteEntry ( RD_Reason, RD_BufPtr, entry, format ); RD_BufPtr = w_result;
if (w_result != NULL) { RD_ReqCount--;
RD_BufPtr = w_result; RD_CurCount++;
RD_ReqCount--; *taken = true;
RD_ReqOffset++; }
} else {
else { debug0("Oh dear - client ran out of buffer space!\n");
debug0("Oh dear - client ran out of buffer space!\n"); return EOUTOFMEM;
RD_CurOffset++;
return EOUTOFMEM;
}
} }
} }
RD_CurOffset++;
return OK; 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, static err_t Func_ReadDir ( int reason, char *path_name, char *buffer,
int n_names, int dir_offset, int buflen, int *pOutNread, int n_names, int dir_offset, int buflen, int *pOutNread,
int *pOutNextOffset ) int *pOutNextOffset )
{ {
static Transact_SearchContext scon; static Transact_SearchContext con;
int tmp; int one_name;
err_t res; err_t res;
debug2 ( "\n\n>> ReadDir reason %d path %s", reason, path_name ); 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 ---- */ /* Make sure the number of names we read will fit into buffer */
one_name = (reason == FSEntry_Func_Reason_ReadDirectoryEntries) ? 16 :
tmp = (reason == NAMES_ONLY) ? 16 : (reason == FSEntry_Func_Reason_ReadDirectoriesAndInformation) ? 36 : 44;
(reason == MOST_INFO) ? 36 : 44;
#ifdef LONGNAMES #ifdef LONGNAMES
/* Of course, the above calculation assumes that the filename is at most /* 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, ...@@ -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 * unnecessary buffer overruns - especially when there are not very
* many files with long names or even no files with long names. * 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 #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; if ( n_names <= 0 ) return EBADPARAM;
debug1( "Adjusted count=%d\n", n_names );
RD_Reason = reason; RD_Reason = reason;
RD_BufPtr = buffer; RD_BufPtr = buffer;
RD_BufLen = buflen; RD_BufLen = buflen;
RD_CurCount = 0;
RD_ReqCount = n_names; RD_ReqCount = n_names;
RD_ReqOffset = dir_offset;
debug1("Actual count=%d\n", n_names );
/* Convert path adding wildcard search spec */ /* Convert path adding wildcard search spec */
res = Xlt_ConvertPath( path_name, DOSnamebuf ); res = Xlt_ConvertPath( path_name, DOSnamebuf );
if ( res != OK ) return res; if ( res != OK ) return res;
if ( DOSnamebuf[strlen( DOSnamebuf ) - 1] != '\\' )
tmp = strlen(DOSnamebuf); strcat( DOSnamebuf, "\\");
#ifdef LONGNAMES #ifdef LONGNAMES
if ( DOSnamebuf[tmp-1] == '\\' ) strcat( DOSnamebuf, "*" );
strcpy( DOSnamebuf+tmp, "*" );
else
strcpy( DOSnamebuf+tmp, "\\*" );
#else #else
if ( DOSnamebuf[tmp-1] == '\\' ) strcat( DOSnamebuf, "????????.???" );
strcpy( DOSnamebuf+tmp, "????????.???" );
else
strcpy( DOSnamebuf+tmp, "\\????????.???" );
#endif #endif
/* Start a new search? ----------------------------------- */ /* Start a new search? */
if (dir_offset == 0)
if ( RD_ReqOffset == 0 || /* New start */
RD_ReqOffset < RD_CurOffset || /* Going back in search */
strcmp(DOSnamebuf, RD_CurrentPath) != 0 ) /* New directory */
{ {
debug1("\n>> Start search (%s)\n", DOSnamebuf); debug2( ">> Start search (%s) count %d\n", DOSnamebuf, RD_ReqCount);
strcpy ( RD_CurrentPath, DOSnamebuf); con.resume_key = 0;
RD_CurOffset = 0; res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount+RD_ReqOffset, Dir_CallbackFn, NULL, &con );
Dir_CallbackFn, NULL, &scon );
} }
else else {
con.resume_key = dir_offset;
res = OK; res = OK;
}
/* Continue search, if needs be */ /* Continue search, if needs be */
while ( res == OK && /* More names available */ while ( res == OK && /* More names available */
RD_ReqCount > 0 ) /* More names wanted */ RD_ReqCount > 0 ) /* More names wanted */
{ {
debug0("\n>> Continue search\n"); debug3( ">> Continue search (%s) count %d resume %08x\n", DOSnamebuf, RD_ReqCount, con.resume_key);
res = SMB_ReadDirEntries ( NULL, RD_ReqCount+RD_ReqOffset-RD_CurOffset, res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
Dir_CallbackFn, NULL, &scon ); Dir_CallbackFn, NULL, &con );
} }
/* Process results */ /* Process results */
if (res == EOUTOFMEM && RD_BufLen == -1) { if (res == EOUTOFMEM && RD_BufLen == -1) {
/* Special result when client buffer space exhausted */ /* Special result when client buffer space exhausted */
debug0("Client buffer space was exhausted\n"); debug0("Client buffer space was exhausted\n");
res = OK; res = OK;
} }
debug2("End search, res=%d RD_ReqCount=%d\n", res, RD_ReqCount); debug2("End search, res=%d RD_ReqCount=%d\n", res, RD_ReqCount);
if ( res != OK ) /* Ran out of files, or error */ if ( res != OK ) { /* Ran out of files, or error */
{
RD_CurrentPath[0] = 0; /* Stop any repeat searches */
*pOutNextOffset = -1; *pOutNextOffset = -1;
} }
else else
{ *pOutNextOffset = con.resume_key;
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;
*pOutNread = RD_CurCount;
if ( res == ENOMOREFILES ) if ( res == ENOMOREFILES )
return OK; return OK;
return res; return res;
} }
#if 0 /* Never called */
static err_t Func_ReadFreeSpace ( int sixtyfourbit, char *name, int *R ) static err_t Func_ReadFreeSpace ( int sixtyfourbit, char *name, int *R )
{ {
_kernel_swi_regs r; _kernel_swi_regs r;
_kernel_oserror *err; _kernel_oserror *err;
struct disk_size_response dsr;
if (sixtyfourbit)
r.r[0] = 2; {
r.r[2] = (int) &dsr; fspc_64 dsr[3];
r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r); r.r[0] = 4;
if (err != NULL) r.r[2] = (int) &dsr;
return ENOTPRESENT; r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r);
R[0] = dsr.freeblks; if (err != NULL)
if (sixtyfourbit) { return ENOTPRESENT;
R[1] = R[4] = 0;
R[0] = dsr[1].lo;
R[1] = dsr[1].hi;
R[2] = 0x7FFFFFFF; 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[1] = 0x7FFFFFFF;
R[2] = dsr.totalblks; R[2] = dsr.totalblks;
} }
return OK; return OK;
} }
#endif
/* Func ============================================================= */ /* Func ============================================================= */
_kernel_oserror *fsentry_func ( int *R ) _kernel_oserror *fsentry_func ( int *R )
{ {
err_t err; err_t err;
bool flushnames = false;
debug1("FS_func(%d)", R[0] ); debug1("FS_func(%d)", R[0] );
...@@ -423,8 +382,10 @@ _kernel_oserror *fsentry_func ( int *R ) ...@@ -423,8 +382,10 @@ _kernel_oserror *fsentry_func ( int *R )
} }
} }
#endif #endif
if ( err == OK ) if ( err == OK ) {
err = SMB_Rename ( DOSnamebuf, DOSnamebuf+DOS_NAME_LEN ); err = SMB_Rename ( DOSnamebuf, DOSnamebuf+DOS_NAME_LEN );
flushnames = true;
}
#ifdef LONGNAMES #ifdef LONGNAMES
if (SMB_IsLongNameFS(DOSnamebuf + DOS_NAME_LEN)) { if (SMB_IsLongNameFS(DOSnamebuf + DOS_NAME_LEN)) {
...@@ -476,40 +437,29 @@ _kernel_oserror *fsentry_func ( int *R ) ...@@ -476,40 +437,29 @@ _kernel_oserror *fsentry_func ( int *R )
case FSEntry_Func_Reason_BootFilingSystem: case FSEntry_Func_Reason_BootFilingSystem:
LM_Boot(); LM_Boot();
err = OK; err = OK;
flushnames = true;
break; break;
case FSEntry_Func_Reason_ShutDown: case FSEntry_Func_Reason_ShutDown:
/* On shutdown, disconnect all drives */ /* On shutdown, disconnect all drives */
err = SMB_Shutdown(); err = SMB_Shutdown();
break; flushnames = true;
break;
case FSEntry_Func_Reason_ReadDirectoryEntries: case FSEntry_Func_Reason_ReadDirectoryEntries:
case FSEntry_Func_Reason_ReadDirectoriesAndInformation: case FSEntry_Func_Reason_ReadDirectoriesAndInformation:
case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation: case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation:
err = Func_ReadDir ( R[0], name_R(1), name_R(2), err = Func_ReadDir ( R[0], name_R(1), name_R(2),
R[3], R[4], R[5], &R[3], &R[4] ); 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; 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: default:
err = EBADPARAM; err = EBADPARAM;
break; break;
} }
#ifdef LONGNAMES #ifdef LONGNAMES
NameCache_Flush(ncf_FSFUNC_EXIT); if (flushnames) NameCache_Flush(ncf_FSFUNC_EXIT);
#endif #endif
return Xlt_Error(err); return Xlt_Error(err);
...@@ -542,6 +492,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -542,6 +492,7 @@ _kernel_oserror *fsentry_file( int *R )
int tmp; int tmp;
DOS_ATTRIBS da; DOS_ATTRIBS da;
RISCOS_ATTRIBS ra; RISCOS_ATTRIBS ra;
bool flushnames = false;
debug1("FS_file(%d)", R[0] ); debug1("FS_file(%d)", R[0] );
...@@ -570,6 +521,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -570,6 +521,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.execaddr = R[3]; ra.execaddr = R[3];
ra.flags = ROA_READ | ROA_WRITE; ra.flags = ROA_READ | ROA_WRITE;
Xlt_CnvROtoDOS(&ra, &da, CNV_DATETIME | CNV_ATTRIBS ); Xlt_CnvROtoDOS(&ra, &da, CNV_DATETIME | CNV_ATTRIBS );
flushnames = true;
#ifdef LONGNAMES #ifdef LONGNAMES
strncpy(DOSnamebuf + DOS_NAME_LEN, DOSnamebuf, DOS_NAME_LEN); strncpy(DOSnamebuf + DOS_NAME_LEN, DOSnamebuf, DOS_NAME_LEN);
if (Xlt_AddROType(DOSnamebuf, ra.loadaddr)) { if (Xlt_AddROType(DOSnamebuf, ra.loadaddr)) {
...@@ -637,6 +589,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -637,6 +589,7 @@ _kernel_oserror *fsentry_file( int *R )
break; break;
} }
flushnames = true;
if ( R[0] == FSEntry_File_Reason_WriteLoadAddress ) if ( R[0] == FSEntry_File_Reason_WriteLoadAddress )
{ {
ra.loadaddr = R[2]; ra.loadaddr = R[2];
...@@ -675,6 +628,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -675,6 +628,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.loadaddr = R[2]; ra.loadaddr = R[2];
ra.execaddr = R[3]; ra.execaddr = R[3];
ra.flags = R[5]; ra.flags = R[5];
flushnames = true;
#ifdef LONGNAMES #ifdef LONGNAMES
{ {
...@@ -706,6 +660,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -706,6 +660,7 @@ _kernel_oserror *fsentry_file( int *R )
R[3] = ra.execaddr; R[3] = ra.execaddr;
R[4] = da.length; R[4] = da.length;
R[5] = ra.flags; R[5] = ra.flags;
flushnames = true;
if ( da.attr & ATTR_DIR ) if ( da.attr & ATTR_DIR )
{ {
...@@ -725,8 +680,9 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -725,8 +680,9 @@ _kernel_oserror *fsentry_file( int *R )
break; break;
case FSEntry_File_Reason_CreateDirectory: case FSEntry_File_Reason_CreateDirectory:
Xlt_CnvRenameX2 ( DOSnamebuf, DOSnamebuf ); Xlt_CnvRenameX2 ( DOSnamebuf, DOSnamebuf );
err = SMB_MkDir ( DOSnamebuf ); err = SMB_MkDir ( DOSnamebuf );
flushnames = true;
break; break;
/* Read information calls ---------------------------- */ /* Read information calls ---------------------------- */
...@@ -759,7 +715,7 @@ _kernel_oserror *fsentry_file( int *R ) ...@@ -759,7 +715,7 @@ _kernel_oserror *fsentry_file( int *R )
} }
#ifdef LONGNAMES #ifdef LONGNAMES
NameCache_Flush(ncf_FSFILE_EXIT); if (flushnames) NameCache_Flush(ncf_FSFILE_EXIT);
#endif #endif
return Xlt_Error(err); return Xlt_Error(err);
...@@ -1058,6 +1014,7 @@ bool FS_Init(void) ...@@ -1058,6 +1014,7 @@ bool FS_Init(void)
for ( i=0; i<MAXFILES; i++ ) for ( i=0; i<MAXFILES; i++ )
FileTbl[i].Free = true; FileTbl[i].Free = true;
NextHandle = 0; NextHandle = 0;
return true; return true;
} }
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include "netbios.h" #include "netbios.h"
#include "SMB.h" #include "SMB.h"
#include "xlate.h" #include "xlate.h"
#include "version.h" #include "VersionNum"
#include "omni.h" #include "omni.h"
#include "printers.h" #include "printers.h"
#include "RPC.h" #include "RPC.h"
...@@ -92,13 +92,6 @@ struct NETBIOS_TRANSPORT *NB_ActiveTransport; /* Selected net transport */ ...@@ -92,13 +92,6 @@ struct NETBIOS_TRANSPORT *NB_ActiveTransport; /* Selected net transport */
static pfnTransportInit NB_InitedTransport; /* Identify active transport */ static pfnTransportInit NB_InitedTransport; /* Identify active transport */
static bool LM_Declared; /* True if we're registered as a filing system */ static bool LM_Declared; /* True if we're registered as a filing system */
/* ------------------------------- */
char Default_FileTName[6];
int Default_FileType;
/* ------------------------------- */
#define CMOS_FSNUMBER 5 #define CMOS_FSNUMBER 5
...@@ -340,21 +333,6 @@ static _kernel_oserror *Cmd_LanMan ( const char *args ) ...@@ -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 ) static _kernel_oserror *Cmd_Free ( const char *args )
{ {
_kernel_swi_regs r; _kernel_swi_regs r;
...@@ -376,18 +354,18 @@ static _kernel_oserror *Cmd_Free ( const char *args ) ...@@ -376,18 +354,18 @@ static _kernel_oserror *Cmd_Free ( const char *args )
if (e == NULL) { if (e == NULL) {
if (values[3] == 0 && values[5] == 0) { 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) { if (values[4] != -1) {
printf("Bytes used &%08x\n", values[4] ); printf("Bytes used &%08X\n", values[4] );
} }
else { else {
printf("Bytes used unavailable\n"); printf("Bytes used unavailable\n");
} }
} }
else { 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) { 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 { else {
printf("Bytes used unavailable\n"); printf("Bytes used unavailable\n");
...@@ -478,12 +456,15 @@ static void SetDefaultVars ( void ) ...@@ -478,12 +456,15 @@ static void SetDefaultVars ( void )
char fs_name [ FSERVER_LEN+1 ]; char fs_name [ FSERVER_LEN+1 ];
#ifdef DEBUG #ifdef DEBUG
LM_Vars.verbose = true; /* DEBUG NAS */ LM_Vars.verbose = true; /* DEBUG NAS */
#else #else
LM_Vars.verbose = false; LM_Vars.verbose = false;
#endif #endif
LM_Vars.initialised = LMInitState_Uninitialised; LM_Vars.initialised = LMInitState_Uninitialised;
LM_Vars.namemode = NM_FIRSTCAPS;
/* See where IP packets are going to be sent */
name = getenv("Inet$EtherType"); name = getenv("Inet$EtherType");
strcpyn ( LM_Vars.drivername, strcpyn ( LM_Vars.drivername,
(name==NULL) ? DEFAULT_ETHER_TYPE : name, NAME_LIMIT ); (name==NULL) ? DEFAULT_ETHER_TYPE : name, NAME_LIMIT );
...@@ -500,10 +481,26 @@ static void SetDefaultVars ( void ) ...@@ -500,10 +481,26 @@ static void SetDefaultVars ( void )
if ( name != NULL ) *name = 0; if ( name != NULL ) *name = 0;
} }
/* Following 'get from CMOS' bits added 980127:RCE * /* See if the user has overridden the default filetype */
* to address user complain that it has to be typed in every time * 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(); Lgn_Init();
GetFSName(fs_name); GetFSName(fs_name);
if (fs_name[0] != '\0') if (fs_name[0] != '\0')
...@@ -511,20 +508,6 @@ static void SetDefaultVars ( void ) ...@@ -511,20 +508,6 @@ static void SetDefaultVars ( void )
strcpy(LM_Vars.workgroup,fs_name); 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 */ /* Set transport type from CMOS, unless overridden on command line */
#ifdef NO_NETBEUI #ifdef NO_NETBEUI
LanMan_InitTransport(NB_NBIP_Setup); LanMan_InitTransport(NB_NBIP_Setup);
...@@ -564,7 +547,10 @@ static _kernel_oserror *Cmd_LMInfo ( const char *args ) ...@@ -564,7 +547,10 @@ static _kernel_oserror *Cmd_LMInfo ( const char *args )
(void) args; (void) args;
Omni_Debug(); Omni_Debug();
if (LM_Vars.verbose) if (LM_Vars.verbose)
printf("Status: %s\n", LM_Status()); {
printf("Status: %s\n", LM_Status());
Stat_Show();
}
return NULL; return NULL;
} }
...@@ -641,15 +627,6 @@ static _kernel_oserror *Cmd_LMPrinters ( const char *args ) ...@@ -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 ) static _kernel_oserror *Cmd_FS ( const char *args )
{ {
/* This is a *Configure/Status command handler - it's therefore unusual */ /* This is a *Configure/Status command handler - it's therefore unusual */
...@@ -792,7 +769,6 @@ static CommandFnPtr Cmd_Dispatch[] = ...@@ -792,7 +769,6 @@ static CommandFnPtr Cmd_Dispatch[] =
CmdEntry(LMLogoff), CmdEntry(LMLogoff),
CmdEntry(LMServer), CmdEntry(LMServer),
CmdEntry(LMPrinters), CmdEntry(LMPrinters),
CmdEntry(LMStats),
CmdEntry(FS), CmdEntry(FS),
CmdEntry(LMTransport), CmdEntry(LMTransport),
CmdEntry(LMNameServer), CmdEntry(LMNameServer),
...@@ -936,7 +912,7 @@ static err_t ProcessCmdLine ( const char *_line ) ...@@ -936,7 +912,7 @@ static err_t ProcessCmdLine ( const char *_line )
case 'H': case 'H':
case '?': 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" "\nWritten by Ian Harvey 1994-1996\nUse:\n"
"\t-dea0\tto use 'ea0' for network driver (etc)\n" "\t-dea0\tto use 'ea0' for network driver (etc)\n"
"\t-n\tto disable network browsing\n" "\t-n\tto disable network browsing\n"
...@@ -1183,7 +1159,7 @@ static _kernel_oserror *LM_init_phase_2(void) ...@@ -1183,7 +1159,7 @@ static _kernel_oserror *LM_init_phase_2(void)
/*LM_StartupBoot();*/ /*LM_StartupBoot();*/
if (want_boot) { if (want_boot) {
if (LM_Vars.verbose) printf("Booting ...\n"); if (LM_Vars.verbose) printf("Booting...\n");
LM_Boot(); LM_Boot();
} }
......
...@@ -92,7 +92,7 @@ ...@@ -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 */ int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */ struct FindName_res *pRes; /* Pointer to result buf */
...@@ -273,8 +273,11 @@ EXPORT nametype_t _NB_DecodeName ( NETNAME *pnn, char *buf ) ...@@ -273,8 +273,11 @@ EXPORT nametype_t _NB_DecodeName ( NETNAME *pnn, char *buf )
static uint NB_GetTime (void) static uint NB_GetTime (void)
{ {
/* This is well-defined for RISCOS */ uint tick;
return * (uint *)0x10C;
/* Centisecond tick */
(void) _swix(OS_ReadMonotonicTime, _OUT(0), &tick);
return tick;
} }
...@@ -1334,7 +1337,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn ) ...@@ -1334,7 +1337,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
NBIP_CallbackFn_handler(); NBIP_CallbackFn_handler();
if (pNE->status == RMT_FOUND) 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; return pNE;
} }
} }
...@@ -1358,7 +1361,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn ) ...@@ -1358,7 +1361,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
pNE->TTL_StartTime = NB_GetTime(); pNE->TTL_StartTime = NB_GetTime();
pNE->TTL_Interval = 1; /* Doesn't last for long */ pNE->TTL_Interval = 1; /* Doesn't last for long */
pNE->IPaddress = GetIPAddr ( (BYTE *) (pHE->h_addr_list[0]) ); 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; return pNE;
} }
...@@ -1626,7 +1629,7 @@ static bool ReadData ( int sid, BYTE *where, int len, uint timeout, int flags ) ...@@ -1626,7 +1629,7 @@ static bool ReadData ( int sid, BYTE *where, int len, uint timeout, int flags )
if ( NB_GetTime() - tstart > timeout ) if ( NB_GetTime() - tstart > timeout )
{ {
debug0("Timeout\n"); if ( timeout > 0) debug1("Timeout after %dcs\n", timeout);
return false; return false;
} }
} }
...@@ -1641,7 +1644,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd ) ...@@ -1641,7 +1644,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
struct sockaddr_in sa; struct sockaddr_in sa;
BYTE *p; uint len; 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) ); 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 /* 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 ) ...@@ -1698,7 +1701,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
return EDATALEN; return EDATALEN;
pNS->rmt_addr.sin_addr = GetIPAddr( DatagramBuf ); pNS->rmt_addr.sin_addr = GetIPAddr( DatagramBuf );
pNS->rmt_addr.sin_port = htons(GetShort( DatagramBuf+4 )); 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) ); pNS->rmt_addr.sin_addr.s_addr, ntohs(pNS->rmt_addr.sin_port) );
return ERETARGET; return ERETARGET;
} }
......
...@@ -102,18 +102,17 @@ static void NameCache_Exit(void) ...@@ -102,18 +102,17 @@ static void NameCache_Exit(void)
{ {
free(NameCache.data); free(NameCache.data);
NameCache.data = NULL; NameCache.data = NULL;
debug1("NameCache hits: %d\n", NameCache.hits);
} }
void NameCache_Flush(ncf_reason why) 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 (why == ncf_REINIT) NameCache.hits = 0;
if (NameCache.data) { if (NameCache.data) {
NameCache.head = 0; NameCache.head = 0;
NameCache.tail = 0; NameCache.tail = 0;
NameCache.last = -1; NameCache.last = -1;
((rec_hdr *) NameCache.data) -> offset_next = -1; ((rec_hdr *) NameCache.data) -> offset_next = -1;
} }
} }
......
...@@ -85,7 +85,7 @@ ...@@ -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 */ int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */ struct FindName_res *pRes; /* Pointer to result buf */
......
This diff is collapsed.
This diff is collapsed.
...@@ -28,16 +28,14 @@ ...@@ -28,16 +28,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include "kernel.h"
#include "stdtypes.h" #include "stdtypes.h"
#include "swis.h" #include "swis.h"
#include "Xlate.h" #include "Xlate.h"
#include "attr.h" #include "attr.h"
#include "omni.h" #include "omni.h"
#include "LanMan.h"
#include "lmvars.h" #include "lmvars.h"
#include "SMB.h" #include "SMB.h"
#include "Transact.h"
#include "NameCache.h" #include "NameCache.h"
#ifdef LONGNAMES #ifdef LONGNAMES
...@@ -50,13 +48,6 @@ ...@@ -50,13 +48,6 @@
*/ */
static const int deaddead = (int)0xDEADDEAD; 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 /* Macro returns non-zero if the specifiec load addressis indicative of
* a filetyped object. Rather than checking for the top 12 bits being * 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 * set, it's much quicker to arithmetic shift it right 20 bits and test
...@@ -75,8 +66,7 @@ static const int untyped_exec = 0x03800000; ...@@ -75,8 +66,7 @@ static const int untyped_exec = 0x03800000;
* ORR rn, rn, #0x0FF00000: MOV load,load,LSL #12: * ORR rn, rn, #0x0FF00000: MOV load,load,LSL #12:
* EOR load, type, load LSR #20: EOR load,rn,load LSL #8 * EOR load, type, load LSR #20: EOR load,rn,load LSL #8
*/ */
#define ENCODE_FILETYPE(load,type) \ #define ENCODE_FILETYPE(load,type) (((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
(((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
#endif #endif
...@@ -102,18 +92,18 @@ static const int untyped_exec = 0x03800000; ...@@ -102,18 +92,18 @@ static const int untyped_exec = 0x03800000;
*/ */
int stricmp(const char *first, const char *second) int stricmp(const char *first, const char *second)
{ {
for (;;) { for (;;) {
unsigned int a = *first++; unsigned int a = *first++;
unsigned int b = *second++; unsigned int b = *second++;
if (a == 0) return -b; if (a == 0) return -b;
if (a != b) { if (a != b) {
unsigned int c = (unsigned int) tolower(a); unsigned int c = (unsigned int) tolower(a);
unsigned int d = (unsigned int) tolower(b); unsigned int d = (unsigned int) tolower(b);
signed int result = c - d; signed int result = c - d;
if (result != 0) return result; if (result != 0) return result;
} }
} }
} }
/* strcpyn(): copies a string with given max length. Note that /* strcpyn(): copies a string with given max length. Note that
...@@ -157,7 +147,7 @@ void strcpyn_lower ( char *d, const char *s, int len ) ...@@ -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,
0, /* Jan=31 */ 0, /* Jan=31 */
...@@ -245,7 +235,7 @@ void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pDA, RISCOS_ATTRIBS *pRA, int flags ) ...@@ -245,7 +235,7 @@ void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pDA, RISCOS_ATTRIBS *pRA, int flags )
/* Total = (thi << 16)+tlo; */ /* Total = (thi << 16)+tlo; */
pRA->loadaddr = 0xFFF00000 + ( (thi+ (tlo >> 16) ) >> 16) + 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; pRA->execaddr = (thi << 16) + tlo;
} }
...@@ -376,27 +366,15 @@ static char Xlt_DefaultDrv = 'A'; ...@@ -376,27 +366,15 @@ static char Xlt_DefaultDrv = 'A';
#define CH_WILD 2 #define CH_WILD 2
#define CH_PATH 3 #define CH_PATH 3
#define CH_SEP 4 #define CH_SEP 4
#define CH_DUD '_' #define CH_DUD '_'
/* Current tables set /*
Illegal in DOS names: / < > ? + , ; = [ ] : * \ " | DEL
Illegal in RISCOS names: . $ % # & ^ @ : * \ " | DEL
DOS RISCOS
# ?
$ <
% >
& +
@ =
^ ,
Illegal in RISCOS names: space * " : \ | # $ % & @ ^ DLE
Also: RISCOS { and [ map to DOS (, } and ] to ),
; and top-bit-set chars to _
All control characters and space are bad
All top bit set characters are swapped for _
*/ */
static char xlt_RO2DOS[256] = static char xlt_RO2DOS[256] =
{ {
CH_END, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, /* 00-07 */ 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] = ...@@ -417,7 +395,7 @@ static char xlt_RO2DOS[256] =
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', '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,
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] = ...@@ -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 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 ) static err_t nameROtoDOS ( char *dst, char *src )
{ {
...@@ -510,50 +530,6 @@ 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] = ...@@ -561,7 +537,7 @@ static char xlt_DOS2RO[256] =
void Xlt_NameDOStoRO ( char *dst, char *src ) void Xlt_NameDOStoRO ( char *dst, char *src )
{ {
int i, c; 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 */ 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) ...@@ -754,22 +730,18 @@ static char Xlt_ContentiousCharCheck(char e, char d)
* and that structure is updated with the real filename once a match * and that structure is updated with the real filename once a match
* has been found. The format parameter should always be 1. * 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; Xlt_NXCX2_Data *dst = _dst;
char *eptr = (char *) (entry + 23); char *eptr = (char *) (entry + 23);
char *dptr = 1 + strrchr(dst->matchbuf, '\\'); char *dptr = 1 + strrchr(dst->matchbuf, '\\');
err_t res = OK; err_t res = OK;
*taken = true;
if (dst->dstcpy[0] != '*') { if (dst->dstcpy[0] != '*') {
return EOUTOFMEM; return EOUTOFMEM;
} }
debug3("Xlt_NameXlateCallbackX2: checking `%s', against `%s' in `%s'\n",
(char *) entry + 23,
dptr,
dst->dstcpybuf);
for (;;) { for (;;) {
char e = *eptr++; char e = *eptr++;
char d = *dptr++; char d = *dptr++;
...@@ -820,6 +792,7 @@ static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst ) ...@@ -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 err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
{ {
static Xlt_NXCX2_Data private; static Xlt_NXCX2_Data private;
static Transact_SearchContext con;
char *inptr; char *inptr;
err_t status; err_t status;
...@@ -835,7 +808,9 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level ) ...@@ -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 * private.dstcpy must point at the * character so that the callback
* function can write the matched target name straight in * function can write the matched target name straight in
*/ */
#if 0 /* No side effects */
(void) NameCache_Locate(private.matchbuf); (void) NameCache_Locate(private.matchbuf);
#endif
strcpy(private.dstcpybuf, private.matchbuf); strcpy(private.dstcpybuf, private.matchbuf);
private.dstcpy = strrchr(private.dstcpybuf, '\\'); private.dstcpy = strrchr(private.dstcpybuf, '\\');
if (private.dstcpy) { if (private.dstcpy) {
...@@ -905,24 +880,27 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level ) ...@@ -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 /* Repeatedly search the directory until we find a match, or there are
* no more entries to be read back * no more entries to be read back
*/ */
con.resume_key = 0;
for (status = OK, inptr = private.dstcpybuf; status == OK; inptr = NULL) { for (status = OK, inptr = private.dstcpybuf; status == OK; inptr = NULL) {
status = SMB_ReadDirEntries(inptr, 32, Xlt_NameXlateCallbackX2, status = SMB_ReadDirEntries(inptr, 32, Xlt_NameXlateCallbackX2,
&private, NULL); &private, &con);
switch (status) { switch (status) {
case OK: case OK:
/* More entries to read, and no match found yet */ /* More entries to read, and no match found yet */
break; break;
case EOUTOFMEM: case EOUTOFMEM:
/* Found it */ /* Found it */
strcpy(dst, private.dstcpybuf); strcpy(dst, private.dstcpybuf);
debug1("\n**RIGHT. Got a match: `%s'\n", dst); debug1("**RIGHT. Got a match: `%s'\n", dst);
break; break;
default: default:
/* Definitely didn't find it - revert to original filename /* Definitely didn't find it - revert to original filename
* or at least filename with nasties resolved as far as possible * or at least filename with nasties resolved as far as possible
*/ */
strcpy(dst, private.matchbuf); 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; break;
} }
} }
...@@ -935,7 +913,7 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level ) ...@@ -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 ) static err_t Xlt_NameROtoDOSX2 ( char *dst, char *src )
{ {
return Xlt_NameROtoDOSX2_sub(dst, src, 0); return Xlt_NameROtoDOSX2_sub(dst, src, 0);
} }
#endif #endif
...@@ -1213,8 +1191,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA, ...@@ -1213,8 +1191,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (stricmp(leafname+1, FileString_UntypedFile) == 0) if (stricmp(leafname+1, FileString_UntypedFile) == 0)
{ {
debug0("File is untyped (,lxa)\n"); debug0("File is untyped (,lxa)\n");
pRA->loadaddr = untyped_load; pRA->loadaddr = LM_Vars.untyped_address;
pRA->execaddr = untyped_exec; pRA->execaddr = LM_Vars.untyped_address;
*terminator = leafname; *terminator = leafname;
res = OK; res = OK;
} }
...@@ -1282,8 +1260,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA, ...@@ -1282,8 +1260,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (res != OK) if (res != OK)
{ {
/* No ",ttt" and no mimemap lookup - mark as a Text file */ /* No ",ttt" and no mimemap lookup - mark as default type */
pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, Default_FileType); pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, LM_Vars.default_type);
} }
return res; return res;
...@@ -1294,36 +1272,30 @@ return res; ...@@ -1294,36 +1272,30 @@ return res;
#ifdef LONGNAMES #ifdef LONGNAMES
/* Copies the filetype information from one name to another. /* Copies the filetype information from one name to another.
* Note that the file saving routine actually uses this * Called by "rename object" and "create directory", note
* routine to strip filetype information by passing both * thie routine can be called with src and dst the same
* parameters the same. This must continue to function. * to simply remove an extension. 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)
*/ */
err_t Xlt_CnvRenameX2 ( char *src, char *dst ) err_t Xlt_CnvRenameX2 ( char *src, char *dst )
{ {
RISCOS_ATTRIBS RA; RISCOS_ATTRIBS RA;
char *nterm; // *terminator char *terminator, *nterm;
int cnvq=strcmp(src,dst); // check if just need to strip.. int cnvq = strcmp( src, dst );
// if src and dst are same, check if it should have the ,xxx appended if (Xlt_SplitLeafnameX2( dst, &RA, &nterm ) != OK) {
// 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) {
/* No type information - find end of string */ /* No type information - find end of string */
nterm = strchr(dst, '\0'); nterm = strchr(dst, '\0');
} }
else { 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'; *nterm = '\0';
} }
Xlt_SplitLeafnameX2 ( src, &RA, &nterm ) ; // recover source's filetype
// if not identical strings.. add type if not in dos name if (Xlt_SplitLeafnameX2( src, &RA, &terminator ) && cnvq) {
if (cnvq)Xlt_AddROType (dst,RA.loadaddr); /* If dst and src names truly differ apply src's type to dst */
Xlt_AddROType(dst, RA.loadaddr);
}
return OK; return OK;
} }
#endif #endif
...@@ -1332,7 +1304,7 @@ err_t Xlt_CnvRenameX2 ( char *src, char *dst ) ...@@ -1332,7 +1304,7 @@ err_t Xlt_CnvRenameX2 ( char *src, char *dst )
#ifdef LONGNAMES #ifdef LONGNAMES
/* Adds the type suffix for a RISC OS filename. The type is extracted /* 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 ) int Xlt_AddROType ( char *leafname, uint loadaddr )
{ {
...@@ -1353,7 +1325,7 @@ int Xlt_AddROType ( char *leafname, uint loadaddr ) ...@@ -1353,7 +1325,7 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
sprintf(typebuf+1, "%03x", type); sprintf(typebuf+1, "%03x", type);
} }
// strip any acorn filetype suffix /* Strip any acorn filetype suffix */
if (Xlt_SplitLeafnameX2 ( leafname, &RA, &nterm ) != OK) { if (Xlt_SplitLeafnameX2 ( leafname, &RA, &nterm ) != OK) {
/* No type information - find end of string */ /* No type information - find end of string */
nterm = strchr(leafname, '\0'); nterm = strchr(leafname, '\0');
...@@ -1362,28 +1334,27 @@ int Xlt_AddROType ( char *leafname, uint loadaddr ) ...@@ -1362,28 +1334,27 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
/* Strip old type information in case source didn't have any either */ /* Strip old type information in case source didn't have any either */
*nterm = '\0'; *nterm = '\0';
} }
// check leaf for dos file type, else add acorn extra... /* Check leaf for DOS file type, else add acorn extra... */
if (leafname[1] == ':') if (leafname[1] == ':') {
{
term = strrchr(leafname, '.'); /* strrchr catches names like "file.tar.gz" */ term = strrchr(leafname, '.'); /* strrchr catches names like "file.tar.gz" */
} }
else else {
{
term = strrchr(leafname, '/'); /* strrchr catches names like "file/tar/gz" */ term = strrchr(leafname, '/'); /* strrchr catches names like "file/tar/gz" */
} }
if(term) if (term) {
{ // found a DOS type /* Found a DOS type so check the mimemap */
if(!_swix(MimeMap_Translate,_INR(0,2)|_OUT(3), // so check the mimemap if (!_swix(MimeMap_Translate, _INR(0,2)|_OUT(3),
MMM_TYPE_DOT_EXTN,term, MMM_TYPE_DOT_EXTN, term,
MMM_TYPE_RISCOS,&ftype)) MMM_TYPE_RISCOS, &ftype)) {
{ // got a name valid in RISCOS /* Got a name valid in RISCOS */
sprintf(ftypebuf,",%03x",ftype); sprintf(ftypebuf, ",%03x", ftype);
if(!strcmp(typebuf,ftypebuf)) return 1; // its OK.. no need to append type if (!strcmp(typebuf, ftypebuf)) return 1;
} }
} }
// Don't append ,xxx filetype if its the default /* Don't append ,xxx filetype if its the default */
if(strcmp(typebuf,Default_FileTName))strcat(leafname, typebuf); sprintf(ftypebuf,",%03x",LM_Vars.default_type);
if (strcmp(typebuf,ftypebuf)) strcat(leafname, typebuf);
return 1; return 1;
} }
#endif #endif
......
...@@ -102,7 +102,7 @@ command-keyword-table: LM_Command ...@@ -102,7 +102,7 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMLogoff\r" ), invalid-syntax: "Syntax:\t*LMLogoff\r" ),
LMServer(min-args:1, max-args:17, 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] ...", "Syntax:\t*LMServer server [sharename] [sharename] ...",
fs-command:, fs-command:,
invalid-syntax: "Syntax:\t*LMServer server [sharename] [sharename] ...\r", ), invalid-syntax: "Syntax:\t*LMServer server [sharename] [sharename] ...\r", ),
...@@ -114,13 +114,6 @@ command-keyword-table: LM_Command ...@@ -114,13 +114,6 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMPrinters server [printername] [printername] ...\r", 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, FS(min-args:0, max-args:1,
help-text: "*Configure FS <name> sets the file server or domain name from " 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", "which LanManFS will attempt to boot\rSyntax:\t*Configure FS file-server-name",
...@@ -153,7 +146,7 @@ command-keyword-table: LM_Command ...@@ -153,7 +146,7 @@ command-keyword-table: LM_Command
ListFS(min-args:0, max-args:1, ListFS(min-args:0, max-args:1,
help-text: "*ListFS displays the servers in the current LAN workgroup or\r" 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:, fs-command:,
invalid-syntax: "Syntax:\t*ListFS [server]\r", 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 ...@@ -33,6 +33,8 @@ struct LMvars
char *password_ptr; /* Default password e.g. none */ char *password_ptr; /* Default password e.g. none */
bool verbose; bool verbose;
int initialised; /* Initialisation state */ 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; extern struct LMvars LM_Vars;
...@@ -27,13 +27,6 @@ ...@@ -27,13 +27,6 @@
#define FilingSystemName "LanMan" #define FilingSystemName "LanMan"
#define Our_FS_Number 102 #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_AddFilingSystem 12
#define FSControl_SelectFilingSystem 14 #define FSControl_SelectFilingSystem 14
#define FSControl_RemoveFilingSystem 16 #define FSControl_RemoveFilingSystem 16
......
...@@ -42,7 +42,6 @@ extern void Omni_StartUp ( void ); ...@@ -42,7 +42,6 @@ extern void Omni_StartUp ( void );
extern void Omni_Shutdown ( void ); extern void Omni_Shutdown ( void );
extern void Omni_ClearLists ( void ); extern void Omni_ClearLists ( void );
extern bool Omni_Registered;
extern void Omni_ServiceCall ( _kernel_swi_regs *R ); extern void Omni_ServiceCall ( _kernel_swi_regs *R );
extern void Omni_RecheckInfo ( int flags ); extern void Omni_RecheckInfo ( int flags );
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#define DIRENTRY_SIZE 22 #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 struct disk_size_response
{ {
...@@ -47,9 +47,6 @@ struct disk_size_response ...@@ -47,9 +47,6 @@ struct disk_size_response
#define MAX_SETUPWORDS (4) #define MAX_SETUPWORDS (4)
#endif #endif
typedef union Transact_SearchContext Transact_SearchContext;
struct TransactParms struct TransactParms
{ {
int parms_in_len; int parms_in_len;
...@@ -84,12 +81,7 @@ struct TransactParms ...@@ -84,12 +81,7 @@ struct TransactParms
# define sizeof_TransactParms_external (sizeof(struct TransactParms)) # define sizeof_TransactParms_external (sizeof(struct TransactParms))
#endif #endif
/* Exported routines ================ */
/* Directory functions */ /* Directory functions */
extern err_t SMB_MkDir ( char *path ); extern err_t SMB_MkDir ( char *path );
extern err_t SMB_RmDir ( char *path ); extern err_t SMB_RmDir ( char *path );
extern err_t SMB_Delete ( char *path ); extern err_t SMB_Delete ( char *path );
...@@ -97,12 +89,11 @@ extern err_t SMB_Rename ( char *oldpath, char *newpath ); ...@@ -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_GetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_SetAttribs ( 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, 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 extern err_t SMB_GetFreeSpace ( char lettr, struct disk_size_response
* pDSR ); * pDSR );
/* File functions */ /* File functions */
extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr, extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr,
int *pOutFH ); int *pOutFH );
...@@ -120,19 +111,15 @@ extern err_t SMB_Flush ( int fh ) ; ...@@ -120,19 +111,15 @@ extern err_t SMB_Flush ( int fh ) ;
extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr ); extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr );
/* Printer functions */ /* Printer functions */
extern err_t SMB_OpenPrinter ( char drvlettr, char *printid, int *ph_out ); 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_WritePrinter ( int PH, BYTE *data, int datalen );
extern err_t SMB_ClosePrinter ( int PH ); extern err_t SMB_ClosePrinter ( int PH );
/* Transaction (RPC) functions */ /* Transaction (RPC) functions */
extern err_t SMB_Transact ( char drvlettr, char *trans_name, extern err_t SMB_Transact ( char drvlettr, char *trans_name,
struct TransactParms *pT ); struct TransactParms *pT );
/* Connect/disconnect functions ----------------------- */ /* Connect/disconnect functions */
extern err_t SMB_CreateShare ( int service_type, extern err_t SMB_CreateShare ( int service_type,
int style, int style,
char *serv_name, char *drv_name, char *serv_name, char *drv_name,
...@@ -234,16 +221,16 @@ extern err_t SMB_Shutdown ( void ); ...@@ -234,16 +221,16 @@ extern err_t SMB_Shutdown ( void );
(i) Its contents may become corrupted across any SMB_xxxx calls. (i) Its contents may become corrupted across any SMB_xxxx calls.
The main exception is the SMB_Transact call: this buffer is 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 (ii) It must not be used by anything which may be called during
an SMB call (transmit/receive processing functions, timer an SMB call (transmit/receive processing functions, timer
callbacks, SMB_EnumerateDir callbacks etc). This probably callbacks, SMB_EnumerateDir callbacks etc). This probably
means anything in Network, LLC, and NetBIOS. means anything in Network, LLC, and NetBIOS.
(iii) Any other module (=C source file) may use it freely. In (iii) Any other C source file may use it freely. In
general, it should be assumed corrupted across calls general, it should be assumed corrupted across calls
between modules. between modules.
*/ */
#ifdef LONGNAMES #ifdef LONGNAMES
/* Need a much larger buffer */ /* Need a much larger buffer */
......
...@@ -20,26 +20,22 @@ ...@@ -20,26 +20,22 @@
* *
*/ */
#define SEARCH_ST_SIZE 21
typedef struct ActiveShare *hSHARE; typedef struct ActiveShare *hSHARE;
union Transact_SearchContext { #define SEARCH_ST_SIZE 21
struct Transact1_SearchContext { typedef struct {
bool NextSearchOK; /* Common state */
BYTE SearchState[SEARCH_ST_SIZE]; hSHARE search_drive;
hSHARE SearchDrive; struct TransactParms tp;
} t1; char dir_path[DOS_NAME_LEN];
struct Transact2_SearchContext { DWORD resume_key;
struct Transact1_SearchContext t1; bool resume_key_encountered;
struct TransactParms tp; WORD dir_handle;
DWORD resume_key; bool dir_handle_valid;
WORD dir_handle;
bool dir_handle_valid; /* Cached state for short names */
char last_filename[DOS_NAME_LEN]; BYTE resume_state[SEARCH_ST_SIZE];
} t2; } Transact_SearchContext;
};
extern void Transact_addword(struct TransactParms *TP, int value); extern void Transact_addword(struct TransactParms *TP, int value);
extern void Transact_addlong(struct TransactParms *TP, long 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 ); ...@@ -31,9 +31,9 @@ extern void strcpyn_lower ( char *d, const char *s, int n );
extern void Xlt_Jumble ( char *str ); extern void Xlt_Jumble ( char *str );
extern void Xlt_Unjumble ( char *str ); extern void Xlt_Unjumble ( char *str );
#define CNV_DEFAULT_TYPE FileType_Text
#define CNV_DATETIME 1 #define CNV_DATETIME 1
#define CNV_ATTRIBS 2 #define CNV_ATTRIBS 2
extern void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pInAttr, extern void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pInAttr,
RISCOS_ATTRIBS *pOutAttr, int flags ); RISCOS_ATTRIBS *pOutAttr, int flags );
...@@ -49,6 +49,8 @@ extern void Xlt_NameDOStoRO ( char *riscos_dst, char *dos_src ); ...@@ -49,6 +49,8 @@ extern void Xlt_NameDOStoRO ( char *riscos_dst, char *dos_src );
#define NM_PRESERVED 0 #define NM_PRESERVED 0
#define NM_LOWERCASE 1 #define NM_LOWERCASE 1
#define NM_FIRSTCAPS 2 #define NM_FIRSTCAPS 2
#define NM_INTERNAL 4 /* Can't be selected at the CLI */
/* Mime mappings */ /* Mime mappings */
#define MimeMap_Translate 0x50B00 #define MimeMap_Translate 0x50B00
......