mirror of
https://github.com/obarthel/amiga-smbfs.git
synced 2025-12-08 14:58:35 +00:00
Updated to version 1.166
Please keep in mind that this is still a development version and might surprise you (not necessarily in a good way). Do not let me discourage you to build and test this version, although there will be some risks involved such as data corruption or loss of data.
This commit is contained in:
+175
-143
@@ -3,25 +3,45 @@
|
||||
#include <exec/types.h>
|
||||
#include <exec/ports.h>
|
||||
#include <exec/memory.h>
|
||||
|
||||
#include <dos/dos.h>
|
||||
#include <dos/dosextens.h>
|
||||
#include <dos/exall.h>
|
||||
|
||||
#if defined (__amigaos4__)
|
||||
#include <dos/obsolete.h>
|
||||
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
#else
|
||||
extern struct Library *SysBase;
|
||||
extern struct Library *DOSBase;
|
||||
|
||||
#include <pragmas/exec_pragmas.h>
|
||||
#include <pragmas/dos_pragmas.h>
|
||||
|
||||
#include <clib/exec_protos.h>
|
||||
#include <clib/dos_protos.h>
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* normally you'd include pragmas here */
|
||||
|
||||
#define BUFFSIZE 4096
|
||||
|
||||
int
|
||||
main(int argc,char *argv[])
|
||||
{
|
||||
struct
|
||||
{
|
||||
STRPTR Name;
|
||||
STRPTR Pattern;
|
||||
LONG * BufferSize;
|
||||
} args;
|
||||
|
||||
struct RDArgs * rda;
|
||||
BPTR obj_lock;
|
||||
LONG res2,more;
|
||||
struct ExAllData *Buffer = NULL;
|
||||
struct ExAllData *buffer = NULL;
|
||||
struct ExAllData *ead;
|
||||
struct ExAllControl *control = NULL;
|
||||
LONG rc = RETURN_ERROR;
|
||||
@@ -30,159 +50,171 @@ main(int argc,char *argv[])
|
||||
char owner_bits[9];
|
||||
struct DateTime dat;
|
||||
char date[LEN_DATSTRING],time[LEN_DATSTRING];
|
||||
ULONG total_num_entries = 0;
|
||||
int buffer_size = 0;
|
||||
int type;
|
||||
int i;
|
||||
|
||||
/* ugly argument parsing */
|
||||
if(argc >= 2 && argc <= 3)
|
||||
memset(&args,0,sizeof(args));
|
||||
|
||||
rda = ReadArgs("NAME/A,PATTERN/K,BUF=BUFFER/K/N",(LONG *)&args,NULL);
|
||||
if(rda == NULL)
|
||||
{
|
||||
/* control MUST be allocated by AllocDosObject! */
|
||||
control = (struct ExAllControl *) AllocDosObject(DOS_EXALLCONTROL,NULL);
|
||||
Buffer = (struct ExAllData *) AllocMem(BUFFSIZE,MEMF_PUBLIC|MEMF_CLEAR);
|
||||
|
||||
/* always check allocations! */
|
||||
if (control == NULL || Buffer == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
/* parse the pattern for eac_MatchString */
|
||||
if (ParsePatternNoCase(argv[2],pattern,sizeof(pattern)) == -1)
|
||||
{
|
||||
Printf("ParsePatternNoCase buffer overflow!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
control->eac_MatchString = pattern;
|
||||
}
|
||||
|
||||
/* lock the directory */
|
||||
obj_lock = Lock(argv[1],SHARED_LOCK);
|
||||
if (obj_lock != (BPTR)NULL)
|
||||
{
|
||||
control->eac_LastKey = 0; /* paranoia */
|
||||
|
||||
type = ED_OWNER;
|
||||
|
||||
do /* while more */
|
||||
{
|
||||
more = ExAll(obj_lock,Buffer,BUFFSIZE,type,control);
|
||||
res2 = IoErr();
|
||||
|
||||
if(!more && res2 == ERROR_BAD_NUMBER && type == ED_OWNER)
|
||||
{
|
||||
type = ED_COMMENT;
|
||||
|
||||
more = ExAll(obj_lock,Buffer,BUFFSIZE,type,control);
|
||||
res2 = IoErr();
|
||||
}
|
||||
|
||||
if (!more)
|
||||
{
|
||||
if(res2 != ERROR_NO_MORE_ENTRIES)
|
||||
Printf("Abnormal exit, error = %ld\n",res2);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Printf("Returned %ld entries:\n\n",control->eac_Entries);
|
||||
|
||||
if (control->eac_Entries > 0)
|
||||
{
|
||||
for(ead = Buffer ; ead != NULL ; ead->ed_Next)
|
||||
{
|
||||
if (ead->ed_Type > 0)
|
||||
Printf("%s (dir)", ead->ed_Name);
|
||||
else
|
||||
Printf("%s (file), size=%ld", ead->ed_Name, ead->ed_Size);
|
||||
|
||||
strcpy(user_other_bits, "rwed rwed");
|
||||
|
||||
for(i = 8 ; i < 16 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) == 0)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if(i < 12)
|
||||
offset = 12 - i;
|
||||
else
|
||||
offset = 21 - i;
|
||||
|
||||
user_other_bits[offset - 1] = '-';
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(owner_bits, "hsparwed");
|
||||
|
||||
for(i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) != 0)
|
||||
owner_bits[7 - i] = '-';
|
||||
}
|
||||
|
||||
for(i = 4 ; i < 8 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) == 0)
|
||||
owner_bits[7 - i] = '-';
|
||||
}
|
||||
|
||||
memset(&dat,0,sizeof(dat));
|
||||
|
||||
memset(date,0,sizeof(date));
|
||||
memset(time,0,sizeof(time));
|
||||
|
||||
dat.dat_Stamp.ds_Days = ead->ed_Days;
|
||||
dat.dat_Stamp.ds_Minute = ead->ed_Mins;
|
||||
dat.dat_Stamp.ds_Tick = ead->ed_Ticks;
|
||||
dat.dat_Format = FORMAT_DEF;
|
||||
dat.dat_StrDate = date;
|
||||
dat.dat_StrTime = time;
|
||||
|
||||
DateToStr(&dat);
|
||||
|
||||
Printf(", protection=%s %s (0x%08lx), date=%s %s (%ld/%ld/%ld), comment=\"%s\"",
|
||||
user_other_bits,owner_bits,ead->ed_Prot,
|
||||
date,time,
|
||||
ead->ed_Days,ead->ed_Mins,ead->ed_Ticks,
|
||||
ead->ed_Comment ? ead->ed_Comment : (STRPTR)"");
|
||||
|
||||
if (type == ED_OWNER)
|
||||
{
|
||||
Printf(", uid=%ld, gid=%ld",
|
||||
ead->ed_OwnerUID,
|
||||
ead->ed_OwnerGID);
|
||||
}
|
||||
|
||||
Printf("\n");
|
||||
|
||||
ead = ead->ed_Next;
|
||||
}
|
||||
}
|
||||
|
||||
rc = RETURN_OK; /* success */
|
||||
}
|
||||
while (more);
|
||||
|
||||
UnLock(obj_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Couldn't find %s\n", argv[1]);
|
||||
}
|
||||
PrintFault(IoErr(),FilePart(argv[0]));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(args.BufferSize != NULL)
|
||||
buffer_size = (*args.BufferSize);
|
||||
else
|
||||
buffer_size = BUFFSIZE;
|
||||
|
||||
/* control MUST be allocated by AllocDosObject! */
|
||||
control = (struct ExAllControl *) AllocDosObject(DOS_EXALLCONTROL,NULL);
|
||||
buffer = (struct ExAllData *) AllocMem(buffer_size,MEMF_PUBLIC|MEMF_CLEAR);
|
||||
|
||||
/* always check allocations! */
|
||||
if (control == NULL || buffer == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (args.Pattern != NULL)
|
||||
{
|
||||
Printf("Usage: %s dirname [pattern]\n", argv[0]);
|
||||
/* parse the pattern for eac_MatchString */
|
||||
if (ParsePatternNoCase(args.Pattern,pattern,sizeof(pattern)) == -1)
|
||||
{
|
||||
PrintFault(IoErr(), args.Pattern);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
control->eac_MatchString = pattern;
|
||||
}
|
||||
|
||||
/* lock the directory */
|
||||
obj_lock = Lock(args.Name,SHARED_LOCK);
|
||||
if (obj_lock == (BPTR)NULL)
|
||||
{
|
||||
PrintFault(IoErr(), args.Name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
control->eac_LastKey = 0; /* paranoia */
|
||||
|
||||
/* Workaround for V37 ROM/disk filesystem bug. */
|
||||
type = ED_OWNER;
|
||||
|
||||
Printf("Buffer size = %ld bytes\n", buffer_size);
|
||||
|
||||
do /* while more */
|
||||
{
|
||||
more = ExAll(obj_lock,buffer,buffer_size,type,control);
|
||||
res2 = IoErr();
|
||||
|
||||
/* Workaround for V37 ROM/disk filesystem bug. */
|
||||
if(!more && res2 == ERROR_BAD_NUMBER && type == ED_OWNER)
|
||||
{
|
||||
type = ED_COMMENT;
|
||||
|
||||
more = ExAll(obj_lock,buffer,buffer_size,type,control);
|
||||
res2 = IoErr();
|
||||
}
|
||||
|
||||
if (!more && res2 != ERROR_NO_MORE_ENTRIES)
|
||||
{
|
||||
Printf("Abnormal exit, error = %ld\n",res2);
|
||||
break;
|
||||
}
|
||||
|
||||
Printf("Returned %ld entries:\n\n",control->eac_Entries);
|
||||
|
||||
if (control->eac_Entries == 0)
|
||||
continue;
|
||||
|
||||
for(ead = buffer ; ead != NULL ; ead = ead->ed_Next)
|
||||
{
|
||||
if (ead->ed_Type > 0)
|
||||
Printf("%s (dir)", ead->ed_Name);
|
||||
else
|
||||
Printf("%s (file), size=%ld", ead->ed_Name, ead->ed_Size);
|
||||
|
||||
strcpy(user_other_bits, "rwed rwed");
|
||||
|
||||
for(i = 8 ; i < 16 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) == 0)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if(i < 12)
|
||||
offset = 12 - i;
|
||||
else
|
||||
offset = 21 - i;
|
||||
|
||||
user_other_bits[offset - 1] = '-';
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(owner_bits, "hsparwed");
|
||||
|
||||
for(i = 0 ; i < 4 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) != 0)
|
||||
owner_bits[7 - i] = '-';
|
||||
}
|
||||
|
||||
for(i = 4 ; i < 8 ; i++)
|
||||
{
|
||||
if((ead->ed_Prot & (1 << i)) == 0)
|
||||
owner_bits[7 - i] = '-';
|
||||
}
|
||||
|
||||
memset(&dat,0,sizeof(dat));
|
||||
|
||||
memset(date,0,sizeof(date));
|
||||
memset(time,0,sizeof(time));
|
||||
|
||||
dat.dat_Stamp.ds_Days = ead->ed_Days;
|
||||
dat.dat_Stamp.ds_Minute = ead->ed_Mins;
|
||||
dat.dat_Stamp.ds_Tick = ead->ed_Ticks;
|
||||
dat.dat_Format = FORMAT_DEF;
|
||||
dat.dat_StrDate = date;
|
||||
dat.dat_StrTime = time;
|
||||
|
||||
DateToStr(&dat);
|
||||
|
||||
Printf(", protection=%s %s (0x%08lx), date=%s %s (%ld/%ld/%ld), comment=\"%s\"",
|
||||
user_other_bits,owner_bits,ead->ed_Prot,
|
||||
date,time,
|
||||
ead->ed_Days,ead->ed_Mins,ead->ed_Ticks,
|
||||
ead->ed_Comment ? ead->ed_Comment : (STRPTR)"");
|
||||
|
||||
if (type == ED_OWNER)
|
||||
{
|
||||
Printf(", uid=%ld, gid=%ld",
|
||||
ead->ed_OwnerUID,
|
||||
ead->ed_OwnerGID);
|
||||
}
|
||||
|
||||
Printf("\n");
|
||||
|
||||
total_num_entries++;
|
||||
}
|
||||
}
|
||||
while (more);
|
||||
|
||||
UnLock(obj_lock);
|
||||
|
||||
Printf("Total number of entries = %lu\n", total_num_entries);
|
||||
|
||||
cleanup:
|
||||
|
||||
if (Buffer != NULL)
|
||||
FreeMem(Buffer,BUFFSIZE);
|
||||
if (rda != NULL)
|
||||
FreeArgs(rda);
|
||||
|
||||
if (buffer != NULL)
|
||||
FreeMem(buffer, buffer_size);
|
||||
|
||||
if (control != NULL)
|
||||
FreeDosObject(DOS_EXALLCONTROL,control);
|
||||
FreeDosObject(DOS_EXALLCONTROL, control);
|
||||
|
||||
return(rc);
|
||||
}
|
||||
|
||||
+41
-18
@@ -212,6 +212,7 @@ static BOOL Quit;
|
||||
static BOOL Quiet;
|
||||
static BOOL CaseSensitive;
|
||||
static BOOL OmitHidden;
|
||||
static BOOL DisableExAll;
|
||||
|
||||
static LONG DSTOffset;
|
||||
static LONG TimeZoneOffset;
|
||||
@@ -556,6 +557,7 @@ main(void)
|
||||
KEY VolumeName;
|
||||
NUMBER MaxNameLen;
|
||||
NUMBER CacheSize;
|
||||
SWITCH DisableExAll;
|
||||
NUMBER MaxTransmit;
|
||||
NUMBER Timeout;
|
||||
NUMBER TimeZoneOffset;
|
||||
@@ -592,6 +594,7 @@ main(void)
|
||||
"VOLUME=VOLUMENAME/K,"
|
||||
"MAXNAMELEN/N/K,"
|
||||
"CACHE=CACHESIZE/N/K,"
|
||||
"DISABLEEXALL/S,"
|
||||
"MAXTRANSMIT/N/K,"
|
||||
"TIMEOUT/N/K,"
|
||||
"TZ=TIMEZONEOFFSET/N/K,"
|
||||
@@ -739,6 +742,9 @@ main(void)
|
||||
if(FindToolType(Icon->do_ToolTypes,"CHANGECASE") != NULL)
|
||||
args.ChangeCase = TRUE;
|
||||
|
||||
if(FindToolType(Icon->do_ToolTypes,"DISABLEEXALL") != NULL)
|
||||
args.DisableExAll = TRUE;
|
||||
|
||||
if(FindToolType(Icon->do_ToolTypes,"OMITHIDDEN") != NULL)
|
||||
args.OmitHidden = TRUE;
|
||||
|
||||
@@ -1064,8 +1070,9 @@ main(void)
|
||||
TranslateNames = TRUE;
|
||||
}
|
||||
|
||||
CaseSensitive = (BOOL)args.CaseSensitive;
|
||||
OmitHidden = (BOOL)args.OmitHidden;
|
||||
DisableExAll = (BOOL)(args.DisableExAll != 0);
|
||||
CaseSensitive = (BOOL)(args.CaseSensitive != 0);
|
||||
OmitHidden = (BOOL)(args.OmitHidden != 0);
|
||||
|
||||
/* You don't need to provide a specific workgroup name. smbfs will
|
||||
* work perfectly find with modern (and somewhat older) SMB implementations
|
||||
@@ -6052,7 +6059,7 @@ struct ExAllContext
|
||||
static int
|
||||
dir_scan_callback_func_exall(
|
||||
struct ExAllContext * ec,
|
||||
int unused_fpos,
|
||||
int fpos,
|
||||
int nextpos,
|
||||
const TEXT * name,
|
||||
int eof,
|
||||
@@ -6061,6 +6068,7 @@ dir_scan_callback_func_exall(
|
||||
TEXT translated_name[MAX_FILENAME_LEN+1];
|
||||
int stop_scanning = FALSE;
|
||||
int name_len;
|
||||
int resume_position = -1;
|
||||
LONG type = ec->ec_Type;
|
||||
UBYTE * buffer = ec->ec_Buffer;
|
||||
struct ExAllData * ed;
|
||||
@@ -6167,6 +6175,13 @@ dir_scan_callback_func_exall(
|
||||
SHOWMSG(" this was the first read attempt -- aborting");
|
||||
ec->ec_Error = ERROR_NO_FREE_STORE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assuming that the client wants to know the next
|
||||
* entry, resume with the one which we couldn't store.
|
||||
*/
|
||||
resume_position = fpos;
|
||||
}
|
||||
|
||||
stop_scanning = TRUE;
|
||||
goto out;
|
||||
@@ -6331,7 +6346,7 @@ dir_scan_callback_func_exall(
|
||||
/* Any more entries to deliver or stop right now? */
|
||||
if(stop_scanning || eof)
|
||||
{
|
||||
ec->ec_Control->eac_LastKey = -1;
|
||||
ec->ec_Control->eac_LastKey = resume_position;
|
||||
|
||||
SHOWMSG(" that was the last entry");
|
||||
}
|
||||
@@ -6379,7 +6394,8 @@ Action_ExamineAll(
|
||||
*/
|
||||
if(buffer_size < (LONG)sizeof(ed->ed_Next))
|
||||
{
|
||||
SHOWMSG("buffer is far too short.");
|
||||
D(("buffer is far too short (%ld bytes, minimum is %ld).",buffer_size, sizeof(ed->ed_Next)));
|
||||
|
||||
error = ERROR_NO_FREE_STORE;
|
||||
goto out;
|
||||
}
|
||||
@@ -6387,7 +6403,7 @@ Action_ExamineAll(
|
||||
/* No next entry yet. */
|
||||
ed->ed_Next = NULL;
|
||||
|
||||
if(eac->eac_LastKey == (ULONG)-1)
|
||||
if((LONG)eac->eac_LastKey == -1)
|
||||
{
|
||||
SHOWMSG("scanning already finished.");
|
||||
|
||||
@@ -6531,30 +6547,29 @@ Action_ExamineAll(
|
||||
|
||||
smba_readdir(ln->ln_File,offset,&ec,(smba_callback_t)dir_scan_callback_func_exall,&error);
|
||||
|
||||
if(error == OK && ec.ec_Error != OK)
|
||||
{
|
||||
SHOWMSG("flagging an error");
|
||||
|
||||
SHOWVALUE(ec.ec_Error);
|
||||
|
||||
error = ec.ec_Error;
|
||||
}
|
||||
|
||||
if(error != OK)
|
||||
{
|
||||
SHOWMSG("error whilst scanning");
|
||||
D(("error whilst scanning (errno=%ld)", error));
|
||||
|
||||
error = map_errno_to_ioerr(error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(error == OK && ec.ec_Error != OK)
|
||||
{
|
||||
D(("flagging an error (ioerr=%ld)", ec.ec_Error));
|
||||
|
||||
error = ec.ec_Error;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* The dir_scan_callback_func_exall() function will set the
|
||||
* last key (directory search position) to -1 when there
|
||||
* are no more entries to be read. If we didn't succeed
|
||||
* in reading anything at all, this means that we have to
|
||||
* throw in the towel...
|
||||
*/
|
||||
if(eac->eac_Entries == 0 && ec.ec_Control->eac_LastKey == (ULONG)-1)
|
||||
if(eac->eac_Entries == 0 && (LONG)ec.ec_Control->eac_LastKey == -1)
|
||||
{
|
||||
SHOWMSG("nothing more to be read");
|
||||
|
||||
@@ -6579,7 +6594,7 @@ Action_ExamineAll(
|
||||
{
|
||||
int num_entries_found = 0;
|
||||
|
||||
SHOWVALUE(eac->eac_Entries);
|
||||
D(("number of entries available = %ld",eac->eac_Entries));
|
||||
|
||||
if(eac->eac_Entries > 0)
|
||||
{
|
||||
@@ -8769,6 +8784,14 @@ file_system_handler(BOOL raise_priority, const TEXT * device_name,const TEXT * v
|
||||
case ACTION_EXAMINE_ALL:
|
||||
/* FileLock,ExAllData(APTR),Size,Type,ExAllControl(APTR) -> Bool */
|
||||
|
||||
/* Pretend that we do not support the ExAll() functionality? */
|
||||
if(DisableExAll)
|
||||
{
|
||||
res1 = DOSFALSE;
|
||||
res2 = ERROR_ACTION_NOT_KNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
res1 = Action_ExamineAll(dp->dp_Port,(struct FileLock *)BADDR(dp->dp_Arg1),(UBYTE *)dp->dp_Arg2,
|
||||
dp->dp_Arg3,dp->dp_Arg4,(struct ExAllControl *)dp->dp_Arg5,&res2);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 165
|
||||
#define DATE "19.7.2018"
|
||||
#define VERS "smbfs 1.165"
|
||||
#define VSTRING "smbfs 1.165 (19.7.2018)\r\n"
|
||||
#define VERSTAG "\0$VER: smbfs 1.165 (19.7.2018)"
|
||||
#define REVISION 166
|
||||
#define DATE "20.7.2018"
|
||||
#define VERS "smbfs 1.166"
|
||||
#define VSTRING "smbfs 1.166 (20.7.2018)\r\n"
|
||||
#define VERSTAG "\0$VER: smbfs 1.166 (20.7.2018)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
165
|
||||
166
|
||||
|
||||
Reference in New Issue
Block a user