From 561ca54b8f6d3957294b20e91cf68df0fb3dd243 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Thu, 28 Feb 2019 11:04:35 +0100 Subject: [PATCH] Updated to version 2.20 If the Examine/ExNext/ExAll functions need to restart directory scanning, the cache maintained by the smbfs directory reader is now always cleared. Removed the directory cache expiration time feature, along with the just-introduced CACHEEXPIRES option. The context in which the expiration time was used did not justify it as a feature. It looked more like a bug... Rewrote the smba_readdir() function to perform its only task in a much simpler manner. It now either fills the directory cache or retrieves the cache entries to be delivered to the caller, resuming the retrieval at a predefined position if required. --- README.md | 29 +-- documentation/history.doc | 15 ++ documentation/smbfs.doc | 25 +- source_code/include/smb/smb_fs.h | 2 +- source_code/include/smb/smb_fs_sb.h | 3 - source_code/main.c | 49 ++-- source_code/proc.c | 342 +++++++++++++-------------- source_code/smb_abstraction.c | 351 +++++++++++++--------------- source_code/smb_abstraction.h | 4 +- source_code/smbfs_rev.h | 10 +- source_code/smbfs_rev.rev | 2 +- source_code/sock.c | 198 ++++++++-------- 12 files changed, 488 insertions(+), 542 deletions(-) diff --git a/README.md b/README.md index 95cd8d7..dbc6df7 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,6 @@ Here is how the options look like, in alphabetical order (as command line parame
 ADDVOLUME/K
 CACHE=CACHESIZE/N/K
-CACHEEXPIRES/N/K
 CACHETABLES/N/K
 CASE=CASESENSITIVE/S
 CHANGEUSERNAMECASE/K
@@ -206,9 +205,9 @@ This parameter takes the form of `//server-name/share-name` or `//server-name:po
 
 For example `//sourcery/all`, `//192.168.0.1/all`, `//nas:445/files`, `//nas:microsoft-ds/files` would all be valid `SHARE` parameters.
 
-In this example `server-name` must be either the IPv4 address of the file server to connect to, or the name of the server (note that server names cannot be longer than 16 characters).
+In this example `server-name` must be either the IPv4 address of the file server to connect to, or the name of the server (**note that server names cannot be longer than 16 characters**).
 
-If necessary, you can specify which port number should be used when making the connection. The port number is optional, though. In place of the port (e.g. 445) number you can also use the name of a TCP/UDP service (e.g. "microsoft-ds").
+If necessary, you can specify which port number should be used when making the connection. The port number is optional, though. In place of the port (e.g. 445) number you can also use the name of a TCP/UDP service (e.g. `microsoft-ds`).
 
 Finally, you need to tell the *SMB* server which service you want to connect to, which for the **smbfs** program should be the name of a shared network file system. In the example the name of the shared network file system would be `share-name`.
 
@@ -218,7 +217,7 @@ Unless you use the `VOLUMENAME` option (e.g. `VOLUMENAME=MyData`), **smbfs** wil
 
 In order to connect to an *SMB* share, the server requires that a user name is provided. If you omit the user name, the **smbfs** program will use `GUEST` as a replacement.
 
-If you do provide a user name, it must not be longer than 63 characters. Unless you use the `CHANGEUSERNAMECASE=NO` option the name you provide will be translated to all upper case characters.
+If you do provide a user name, **it must not be longer than 63 characters**. Unless you use the `CHANGEUSERNAMECASE=NO` option the name you provide will be translated to all upper case characters.
 
 You need not provide for a user name on the command line. Alternatively, you may configure an environment variable whose contents will be used instead. The variable could be set up like this:
 
@@ -270,7 +269,7 @@ However, it may be required to change the password to all-uppercase characters b
 
 This option may be omitted, in which case the **smbfs** program will ask the file server about the work group which it is a member of. Should the server fail to respond with this information, the **smbfs** program will use `WORKGROUP` as the domain name.
 
-You should not need to specify the name of the work group or domain which the file server to connect to is a member of. However, if you do need to use it, you must make sure that the name is not longer than 16 characters. The name you provide will be translated to all upper case characters.
+You should not need to specify the name of the work group or domain which the file server to connect to is a member of. However, if you do need to use it, you must **make sure that the name is not longer than 16 characters**. The name you provide will be translated to all upper case characters.
 
 You need not provide for a work group or domain name on the command line. Alternatively, you may configure an environment variable whose contents will be used instead. The variable could be set up like this:
 
@@ -295,7 +294,7 @@ In some cases this may be undesirable as the computer's name differs from what t
 
 You can use the `CLIENT` parameter to tell **smbfs** under which name it should announce itself to the server.
 
-This parameter is optional and will be translated to all upper case characters; it cannot be longer than 16 characters.
+This parameter is optional and will be translated to all upper case characters; **it cannot be longer than 16 characters**.
 
 Please note that the `CLIENT` parameter will be ignored unless the `NETBIOS` switch is used, too.
 
@@ -305,7 +304,7 @@ Please note that the `CLIENT` parameter will be ignored unless the `NETBIOS` swi
 
 In some cases this may be undesirable as the server's name differs from what you specified as the share name. You can use the `SERVER` parameter to tell **smbfs** under which name it should contact the server.
 
-This parameter is optional and will be translated to all upper case characters; it cannot be longer than 16 characters.
+This parameter is optional and will be translated to all upper case characters; **it cannot be longer than 16 characters**.
 
 Please note that the `SERVER` parameter will be ignored unless the `NETBIOS` switch is used, too.
 
@@ -323,7 +322,7 @@ Also note that file and drawer names which cannot be represented on the Amiga du
 
 The built-in default translation method is restricted to the part of Unicode which is covered by the *ISO-8859-1* character set. It is enabled by default, as if `UNICODE=on` had been used. You can disable it with `UNICODE=off`, which completely disables the translation.
 
-Note: some *Samba* versions will return corrupted file and drawer names unless Unicode support is enabled. Names which use only US-ASCII characters appear to be generally safe to use and are unlikely to suffer from corruption.
+**Note**: Some *Samba* versions will return corrupted file and drawer names unless Unicode support is enabled. Names which use only US-ASCII characters appear to be generally safe to use and are unlikely to suffer from corruption.
 
 #### 5.2.2. `CP437/S`
 
@@ -367,29 +366,23 @@ The cache can be used only by one directory at a time, which can cause problems
 
 You can mitigate these effects by increasing the number of caches which **smbfs** may use at a time. By default only a single cache, for a single directory, will be active (`CACHETABLES=1`). You can use more directory caches if you want to, but keep in mind that each cache will consume extra memory. If you want to use multiple caches, you might want to reduce the cache size.
 
-#### 5.3.3. `CACHEEXPIRES/N/K`
-
-There is a limit on how long the contents of a cache are considered "good" until it will have to be refilled. By default a cache will be considered "stale" 10 seconds after it has been filled.
-
-Changing the cache expiration time and the cache size can be necessary if you find that reading and processing (e.g. deleting) directory entries stops or skips certain entries. The large the cache, the longer the expiration time will have to be, and a smaller cache likely requires a shorter expiration time.
-
-#### 5.3.4. `RAISEPRIORITY/S`
+#### 5.3.3. `RAISEPRIORITY/S`
 
 The **smbfs** program can be run at a higher priority than it would normally do (normal would be priority 0), which might increase performance, but raise system load, too. If the `RAISEPRIORITY` switch is used, the **smbfs** program will run at the same priority as other Amiga file systems do (this would be priority 10).
 
-#### 5.3.5. `TIMEOUT/N/K`
+#### 5.3.4. `TIMEOUT/N/K`
 
 The **smbfs** program may lose the connection to the server during file system operations. While it will try to reestablish a connection to the server, some time has to pass before it becomes clear that the server connection is no longer working correctly.
 
 You can set the number of seconds which have to pass before the **smbfs** program will stop waiting for the server to respond, shut down the connection and try again. For example, `TIMEOUT=5` will select a timeout of 5 seconds.
 
-#### 5.3.6. `WRITEBEHIND/S`
+#### 5.3.5. `WRITEBEHIND/S`
 
 The **smbfs** program can try to improve write performance by not waiting for the server to confirm that all the data just transmitted has in fact been stored. There is a risk involved in that the server may not have been able to store the data and you will never know about it.
 
 Please note that the `WRITEBEHIND` switch has no effect if `PROTOCOL=nt1` is used because the **smbfs** program will then be using a different server write command which does not support the "write behind" functionality.
 
-#### 5.3.7. `READTHRESHOLD/N/K` and `WRITETHRESHOLD/N/K`
+#### 5.3.6. `READTHRESHOLD/N/K` and `WRITETHRESHOLD/N/K`
 
 The purpose of **smbfs** is chiefly to enable you to read and write files stored on a networked computer. To this end **smbfs** tries its best to squeeze as much performance out of the data transmission as possible.
 
diff --git a/documentation/history.doc b/documentation/history.doc
index 2fb475f..358a565 100644
--- a/documentation/history.doc
+++ b/documentation/history.doc
@@ -3006,3 +3006,18 @@ smbfs 2.19 (23.2.2019)
   previously was a period of 5 seconds. The current default is 10 seconds,
   which definitely helps. Use the new CACHEEXPIRES option to change how long
   the cache is considered good enough.
+
+
+smbfs 2.20 (27.2.2019)
+
+- If the Examine/ExNext/ExAll functions need to restart directory scanning,
+  the cache maintained by the smbfs directory reader is now always cleared.
+
+- Removed the directory cache expiration time feature, along with the
+  just-introduced CACHEEXPIRES option. The context in which the expiration
+  time was used did not justify it as a feature. It looked more like a bug...
+
+- Rewrote the smba_readdir() function to perform its only task in a much
+  simpler manner. It now either fills the directory cache or retrieves
+  the cache entries to the caller, resuming the retrieval at a predefined
+  position if required.
diff --git a/documentation/smbfs.doc b/documentation/smbfs.doc
index bb2727f..07876e6 100644
--- a/documentation/smbfs.doc
+++ b/documentation/smbfs.doc
@@ -194,7 +194,6 @@ parameters):
 
     ADDVOLUME/K
     CACHE=CACHESIZE/N/K
-    CACHEEXPIRES/N/K
     CACHETABLES/N/K
     CASE=CASESENSITIVE/S
     CHANGEUSERNAMECASE/K
@@ -520,19 +519,7 @@ be active ("CACHETABLES=1"). You can use more directory caches if you want to,
 but keep in mind that each cache will consume extra memory. If you want to use
 multiple caches, you might want to reduce the cache size.
 
-5.3.3. "CACHEEXPIRES/N/K"
-
-There is a limit on how long the contents of a cache are considered "good"
-until it will have to be refilled. By default a cache will be considered
-"stale" 10 seconds after it has been filled.
-
-Changing the cache expiration time and the cache size can be necessary if you
-find that reading and processing (e.g. deleting) directory entries stops or
-skips certain entries. The large the cache, the longer the expiration time
-will have to be, and a smaller cache likely requires a shorter expiration
-time.
-
-5.3.4. "RAISEPRIORITY/S"
+5.3.3. "RAISEPRIORITY/S"
 
 The smbfs program can be run at a higher priority than it would normally do
 (normal would be priority 0), which might increase performance, but raise
@@ -540,7 +527,7 @@ system load, too. If the "RAISEPRIORITY" switch is used, the smbfs program
 will run at the same priority as other Amiga file systems do (this would be
 priority 10).
 
-5.3.5. "TIMEOUT/N/K"
+5.3.4. "TIMEOUT/N/K"
 
 The smbfs program may lose the connection to the server during file system
 operations. While it will try to reestablish a connection to the server, some
@@ -551,7 +538,7 @@ You can set the number of seconds which have to pass before the smbfs program
 will stop waiting for the server to respond, shut down the connection and try
 again. For example, "TIMEOUT=5" will select a timeout of 5 seconds.
 
-5.3.6. "WRITEBEHIND/S"
+5.3.5. "WRITEBEHIND/S"
 
 The smbfs program can try to improve write performance by not waiting for the
 server to confirm that all the data just transmitted has in fact been stored.
@@ -562,7 +549,7 @@ Please note that the "WRITEBEHIND" switch has no effect if "PROTOCOL=nt1" is
 used because the smbfs program will then be using a different server write
 command which does not support the "write behind" functionality.
 
-5.3.7. "READTHRESHOLD/N/K" and "WRITETHRESHOLD/N/K"
+5.3.6. "READTHRESHOLD/N/K" and "WRITETHRESHOLD/N/K"
 
 The purpose of smbfs is chiefly to enable you to read and write files stored
 on a networked computer. To this end smbfs tries its best to squeeze as much
@@ -955,9 +942,9 @@ version 2.1.
 
 8. Credits
 
-The smbfs file system is based upon prior work by Pål-Kristian Engstad, Volker
+The smbfs file system is based upon prior work by P�l-Kristian Engstad, Volker
 Lendecke, Mark A. Shand, Donald J. Becker, Rick Sladkey, Fred N. van Kempen,
-Eric Kasten and Rudolf König. It is a direct descendant of the "Sharity-Light"
+Eric Kasten and Rudolf K�nig. It is a direct descendant of the "Sharity-Light"
 file system written by Christian Starkjohann.
 
 Versions including 1.80 incorporate changes from the MorphOS smbfs
diff --git a/source_code/include/smb/smb_fs.h b/source_code/include/smb/smb_fs.h
index 09b3d5e..1072ccd 100644
--- a/source_code/include/smb/smb_fs.h
+++ b/source_code/include/smb/smb_fs.h
@@ -72,7 +72,7 @@ int smb_proc_mkdir(struct smb_server *server, const char *path, const int len, i
 int smb_proc_rmdir(struct smb_server *server, const char *path, const int len, int * error_ptr);
 int smb_proc_unlink(struct smb_server *server, const char *path, const int len, int * error_ptr);
 int smb_proc_trunc(struct smb_server *server, struct smb_dirent *entry, dword length, int * error_ptr);
-int smb_proc_readdir(struct smb_server *server, const char *path, int fpos, dircache_t * dircache, int * end_of_search_ptr, int * error_ptr);
+int smb_proc_readdir(struct smb_server *server, const char *path, dircache_t * dircache, int * end_of_search_ptr, int * error_ptr);
 int smb_proc_getattr_core(struct smb_server *server, const char *path, int len, struct smb_dirent *entry, int * error_ptr);
 int smb_proc_getattrE(struct smb_server *server, struct smb_dirent *entry, int * error_ptr);
 int smb_query_path_information(struct smb_server *server, const char *path, int len, int fid, struct smb_dirent *entry, int * error_ptr);
diff --git a/source_code/include/smb/smb_fs_sb.h b/source_code/include/smb/smb_fs_sb.h
index 468f847..d3a7b40 100644
--- a/source_code/include/smb/smb_fs_sb.h
+++ b/source_code/include/smb/smb_fs_sb.h
@@ -88,9 +88,6 @@ struct smb_server
 
 	/* olsen (2018-06-11): Prefer SMB core protocol commands over NT1 commands. */
 	int prefer_core_protocol;
-
-	/* olsen (2019-02-23): How many seconds will the directory cache remain valid? */
-	int cache_expires;
 };
 
 #endif
diff --git a/source_code/main.c b/source_code/main.c
index bac974c..cd82fef 100644
--- a/source_code/main.c
+++ b/source_code/main.c
@@ -264,7 +264,7 @@ static ULONG stack_usage_exit(const struct StackSwapStruct * stk);
 static LONG CVSPrintf(const TEXT * format_string, APTR args);
 static int LocalVSNPrintf(STRPTR buffer, int limit, const TEXT * formatString, APTR args);
 static void cleanup(void);
-static BOOL setup(const TEXT * program_name, const TEXT * service, const TEXT * workgroup, STRPTR username, STRPTR opt_password, BOOL opt_change_username_case, BOOL opt_change_password_case, const TEXT * opt_clientname, const TEXT * opt_servername, int opt_cachesize, int opt_cache_tables, int opt_cache_expires, int opt_max_transmit, int opt_timeout, LONG *opt_time_zone_offset, LONG *opt_dst_offset, BOOL opt_raw_smb, BOOL opt_unicode, BOOL opt_prefer_core_protocol, BOOL opt_session_setup_delay_unicode, BOOL opt_write_behind, int opt_smb_request_write_threshold, int opt_smb_request_read_threshold, BOOL scatter_gather, BOOL tcp_no_delay, int socket_receive_buffer_size, int socket_send_buffer_size, const TEXT * device_name, const TEXT * volume_name, BOOL add_volume, const TEXT * translation_file);
+static BOOL setup(const TEXT * program_name, const TEXT * service, const TEXT * workgroup, STRPTR username, STRPTR opt_password, BOOL opt_change_username_case, BOOL opt_change_password_case, const TEXT * opt_clientname, const TEXT * opt_servername, int opt_cachesize, int opt_cache_tables, int opt_max_transmit, int opt_timeout, LONG *opt_time_zone_offset, LONG *opt_dst_offset, BOOL opt_raw_smb, BOOL opt_unicode, BOOL opt_prefer_core_protocol, BOOL opt_session_setup_delay_unicode, BOOL opt_write_behind, int opt_smb_request_write_threshold, int opt_smb_request_read_threshold, BOOL scatter_gather, BOOL tcp_no_delay, int socket_receive_buffer_size, int socket_send_buffer_size, const TEXT * device_name, const TEXT * volume_name, BOOL add_volume, const TEXT * translation_file);
 static void file_system_handler(BOOL raise_priority, const TEXT * device_name, const TEXT * volume_name, const TEXT * service_name);
 
 /****************************************************************************/
@@ -859,7 +859,6 @@ main(void)
 	LONG tz_number, dst_number, debug_number;
 	LONG cache_size = 0;
 	LONG cache_tables = 1;
-	LONG cache_expires = 10;
 	LONG max_transmit = -1;
 	LONG smb_write_threshold = 0;
 	LONG smb_read_threshold = 0;
@@ -1159,18 +1158,6 @@ main(void)
 			args.CacheTables = &cache_tables;
 		}
 
-		str = get_icon_tool_type_value("CACHEEXPIRES",NULL);
-		if(str != NULL)
-		{
-			if(StrToLong(str,&cache_expires) == -1)
-			{
-				report_error("Invalid number '%s' for 'CACHETEXPIRES' parameter.",str);
-				goto out;
-			}
-
-			args.CacheExpires = &cache_expires;
-		}
-
 		str = get_icon_tool_type_value("MAXTRANSMIT", NULL);
 		if(str != NULL)
 		{
@@ -1416,7 +1403,7 @@ main(void)
 			goto out;
 		}
 
-		D(("using 'erroroutput=%s'.", (args.ErrorOutput != NULL) ? "stderr" : "stdout"));
+		D(("using 'erroroutput=%s'.", (args.ErrorOutput != NULL) ? "stdout" : "stderr"));
 
 		ErrorOutput = args.ErrorOutput;
 	}
@@ -1538,16 +1525,6 @@ main(void)
 		}
 	}
 
-	if(args.CacheExpires != NULL)
-	{
-		cache_expires = (*args.CacheExpires);
-		if(cache_expires <= 0)
-		{
-			report_error("'CACHEEXPIRES' parameter must be > 0.");
-			goto out;
-		}
-	}
-
 	if(args.MaxTransmit != NULL)
 	{
 		max_transmit = (*args.MaxTransmit);
@@ -1681,7 +1658,6 @@ main(void)
 	D(("max name length = %ld.", MaxNameLen));
 	D(("cache size = %ld.", cache_size));
 	D(("cache tables = %ld.", cache_tables));
-	D(("cache expires = %ld.", cache_expires));
 	D(("max transmit = %ld.", max_transmit));
 	D(("timeout = %ld.", timeout));
 
@@ -1697,7 +1673,6 @@ main(void)
 		args.ServerName,
 		cache_size,
 		cache_tables,
-		cache_expires,
 		max_transmit,
 		timeout,
 		args.TimeZoneOffset,
@@ -4021,7 +3996,6 @@ setup(
 	const TEXT *	opt_servername,
 	int				opt_cachesize,
 	int				opt_cache_tables,
-	int				opt_cache_expires,
 	int				opt_max_transmit,
 	int				opt_timeout,
 	LONG *			opt_time_zone_offset,
@@ -4273,7 +4247,6 @@ setup(
 		opt_servername,
 		opt_cachesize,
 		opt_cache_tables,
-		opt_cache_expires,
 		opt_max_transmit,
 		opt_timeout,
 		opt_raw_smb,
@@ -7528,6 +7501,7 @@ Action_ExamineNext(
 	struct LockNode * ln;
 	LONG result = DOSFALSE;
 	int error = OK;
+	BOOL restart;
 	LONG offset;
 
 	ENTER();
@@ -7569,12 +7543,14 @@ Action_ExamineNext(
 	if(ln->ln_RestartExamine)
 	{
 		offset = 0;
+		restart = TRUE;
 
 		ln->ln_RestartExamine = FALSE;
 	}
 	else
 	{
 		offset = fib->fib_DiskKey;
+		restart = FALSE;
 	}
 
 	memset(fib,0,sizeof(*fib));
@@ -7582,9 +7558,7 @@ Action_ExamineNext(
 	SHOWMSG("calling 'smba_readdir'");
 	SHOWVALUE(offset);
 
-	smba_readdir(ln->ln_File,offset,fib,(smba_callback_t)dir_scan_callback_func_exnext,NULL,&error);
-
-	if(error != OK)
+	if (smba_readdir(ln->ln_File,offset,restart,fib,(smba_callback_t)dir_scan_callback_func_exnext,NULL,&error) < 0)
 	{
 		SHOWMSG("error whilst scanning");
 		SHOWVALUE(error);
@@ -8025,6 +7999,7 @@ Action_ExamineAll(
 	int error = OK;
 	int eof = FALSE;
 	LONG offset;
+	BOOL restart;
 
 	ENTER();
 
@@ -8181,10 +8156,15 @@ Action_ExamineAll(
 	{
 		SHOWMSG("restarting directory scanning");
 
+		restart = TRUE;
 		offset = 0;
 
 		ln->ln_RestartExamine = FALSE;
 	}
+	else
+	{
+		restart = FALSE;
+	}
 
 	/* Start from the top? Check if the lock actually refers to a directory. */
 	if(offset == 0)
@@ -8214,10 +8194,7 @@ Action_ExamineAll(
 	SHOWMSG("calling 'smba_readdir'");
 	SHOWVALUE(offset);
 
-	smba_readdir(ln->ln_File,offset,&ec,(smba_callback_t)dir_scan_callback_func_exall,&eof,&error);
-
-	/* Did the smba_readdir() run into trouble? */
-	if (error != OK)
+	if (smba_readdir(ln->ln_File,offset,restart,&ec,(smba_callback_t)dir_scan_callback_func_exall,&eof,&error) < 0)
 	{
 		D(("error whilst scanning (errno=%ld)", error));
 
diff --git a/source_code/proc.c b/source_code/proc.c
index 3213951..328ad04 100644
--- a/source_code/proc.c
+++ b/source_code/proc.c
@@ -619,7 +619,7 @@ date_dos2unix (unsigned short time_value, unsigned short date)
 
 		seconds_to_tm(utc_seconds,&tm_utc);
 
-		LOG(("time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+		D(("time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 			tm_utc.tm_year + 1900,
 			tm_utc.tm_mon+1,
 			tm_utc.tm_mday,
@@ -629,7 +629,7 @@ date_dos2unix (unsigned short time_value, unsigned short date)
 
 		seconds_to_tm(seconds,&tm_local);
 
-		LOG(("       %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+		D(("       %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 			tm_local.tm_year + 1900,
 			tm_local.tm_mon+1,
 			tm_local.tm_mday,
@@ -660,7 +660,7 @@ date_unix2dos (int utc_seconds, unsigned short *time_value, unsigned short *date
 
 		seconds_to_tm(utc_seconds,&tm_utc);
 
-		LOG(("time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+		D(("time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 			tm_utc.tm_year + 1900,
 			tm_utc.tm_mon+1,
 			tm_utc.tm_mday,
@@ -670,7 +670,7 @@ date_unix2dos (int utc_seconds, unsigned short *time_value, unsigned short *date
 
 		seconds_to_tm(seconds,&tm_local);
 
-		LOG(("       %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+		D(("       %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 			tm_local.tm_year + 1900,
 			tm_local.tm_mon+1,
 			tm_local.tm_mday,
@@ -922,12 +922,12 @@ smb_errno (int errcls, int error)
 
 		if(err_class != NULL && err_code != NULL)
 		{
-			LOG(("translated error code %ld/%ld (%s/%s) to %ld (%s)\n",
+			D(("translated error code %ld/%ld (%s/%s) to %ld (%s)",
 				errcls,error,err_class->class,err_code->message,result,strerror(result)));
 		}
 		else
 		{
-			LOG(("no proper translation for error code %ld/%ld to %ld (%s)\n",
+			D(("no proper translation for error code %ld/%ld to %ld (%s)",
 				errcls,error,result,strerror(result)));
 		}
 	}
@@ -956,9 +956,9 @@ smb_dump_packet (const byte * packet)
 	errcls = (int) packet[9];
 	error = (int) (int) (packet[11] | ((int)packet[12]) << 8);
 
-	LOG (("smb_len = %ld valid = %ld\n", smb_len (packet), smb_valid_packet (packet)));
-	LOG (("smb_cmd = %ld smb_wct = %ld smb_bcc = %ld\n", packet[8], SMB_WCT (packet), SMB_BCC (packet)));
-	LOG (("smb_rcls = %ld smb_err = %ld\n", errcls, error));
+	D(("smb_len = %ld valid = %ld", smb_len (packet), smb_valid_packet (packet)));
+	D(("smb_cmd = %ld smb_wct = %ld smb_bcc = %ld", packet[8], SMB_WCT (packet), SMB_BCC (packet)));
+	D(("smb_rcls = %ld smb_err = %ld", errcls, error));
 
 	if (errcls)
 		smb_printerr (errcls, error);
@@ -1021,12 +1021,12 @@ smb_request_ok_with_payload (
 	/* smb_request() failed? */
 	if (result < 0)
 	{
-		LOG (("smb_request failed\n"));
+		SHOWMSG("smb_request failed");
 	}
 	/* The message received is inconsistent? */
 	else if ((error = smb_valid_packet (server->transmit_buffer)) != 0)
 	{
-		LOG (("not a valid packet!\n"));
+		SHOWMSG("not a valid packet!");
 
 		(*error_ptr) = error;
 		result = -1;
@@ -1045,14 +1045,14 @@ smb_request_ok_with_payload (
 	 */
 	else if ((error = smb_verify (server->transmit_buffer, command, wct, bcc)) != 0)
 	{
-		LOG (("smb_verify failed\n"));
+		SHOWMSG("smb_verify failed");
 
 		(*error_ptr) = error;
 		result = -1;
 	}
 	else
 	{
-		LOG(("smb_request() returned %ld bytes\n", result));
+		D(("smb_request() returned %ld bytes", result));
 
 		/* Return 0 for success, rather than the number of
 		 * bytes received.
@@ -1089,7 +1089,7 @@ reopen_entry(struct smb_server *server, struct smb_dirent *entry,int * error_ptr
 	{
 		int ignored_error;
 
-		LOG (("trying to reopen file '%s'\n", escape_name(entry->complete_path)));
+		D(("trying to reopen file '%s'", escape_name(entry->complete_path)));
 
 		result = smb_proc_open (server, entry->complete_path, entry->len, entry->writable, FALSE, entry, error_ptr != NULL ? error_ptr : &ignored_error);
 	}
@@ -1124,7 +1124,7 @@ smb_retry (struct smb_server *server)
 
 	if (smb_proc_reconnect (server, &ignored_error) < 0)
 	{
-		LOG (("smb_proc_reconnect failed\n"));
+		SHOWMSG("smb_proc_reconnect failed");
 
 		server->state = CONN_RETRIED;
 		goto out;
@@ -1165,7 +1165,7 @@ smb_setup_header (struct smb_server *server, byte command, int wct, int bcc)
 	ASSERT( smb_frame_size <= (int)server->transmit_buffer_allocation_size );
 
 	if(smb_frame_size > (int)server->transmit_buffer_allocation_size)
-		LOG (("Danger: total packet size (%ld) > transmit buffer allocation (%ld)!\n", smb_frame_size, server->transmit_buffer_allocation_size));
+		D(("Danger: total packet size (%ld) > transmit buffer allocation (%ld)!", smb_frame_size, server->transmit_buffer_allocation_size));
 
 	/* This sets up the NetBIOS session header. 'smb_frame_size'
 	 * is the amount of data that follows the header, in this case
@@ -1202,7 +1202,7 @@ smb_setup_header (struct smb_server *server, byte command, int wct, int bcc)
 
 	WSET (p, 0, bcc);
 
-	LOG (("total packet size=%ld, max receive size=%ld, packet buffer size=%ld\n",
+	D(("total packet size=%ld, max receive size=%ld, packet buffer size=%ld",
 		p + sizeof(word) + bcc - server->transmit_buffer,
 		server->max_recv,
 		server->transmit_buffer_allocation_size
@@ -1244,7 +1244,7 @@ smb_proc_open (
 
 	ENTER();
 
-	LOG(("pathname = '%s'\n", escape_name(pathname)));
+	D(("pathname = '%s'", escape_name(pathname)));
 
 	/* Because the original code opened every file/directory in
 	 * read/write mode, we emulate the same behaviour. Why this
@@ -1377,7 +1377,7 @@ smb_proc_open (
 				(void) smb_copy_data(data, pathname, pathname_size); /* Length includes the terminating NUL byte. */
 			}
 
-			LOG(("requesting SMBntcreateX\n"));
+			SHOWMSG("requesting SMBntcreateX");
 
 			result = smb_request_ok(server, SMBntcreateX, 34, 0, error_ptr);
 			if (result < 0)
@@ -1537,7 +1537,7 @@ smb_proc_open (
 
 			seconds_to_tm(entry->mtime,&tm_utc);
 
-			LOG(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+			D(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 				tm_utc.tm_year + 1900,
 				tm_utc.tm_mon+1,
 				tm_utc.tm_mday,
@@ -1547,7 +1547,7 @@ smb_proc_open (
 
 			seconds_to_tm(DVAL (buf, smb_vwv2),&tm_local);
 
-			LOG(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+			D(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 				tm_local.tm_year + 1900,
 				tm_local.tm_mon+1,
 				tm_local.tm_mday,
@@ -1618,7 +1618,7 @@ smb_proc_read (
 	DSET (buf, smb_vwv2, offset);
 	WSET (buf, smb_vwv4, 0);
 
-	LOG(("requesting %ld bytes\n", count));
+	D(("requesting %ld bytes", count));
 
 	result = smb_request_ok_with_payload (server, SMBread, 5, -1, data, NULL, count, error_ptr);
 	if (result < 0)
@@ -1629,18 +1629,18 @@ smb_proc_read (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 		goto out;
 	}
 
 	/* The buffer format must be 1; smb_request_ok_with_payload() already checked this. */
-	LOG(("buffer_format=%ld, should be %ld\n", BVAL(buf, NETBIOS_HEADER_SIZE+45), 1));
+	D(("buffer_format=%ld, should be %ld", BVAL(buf, NETBIOS_HEADER_SIZE+45), 1));
 
 	result = WVAL (buf, NETBIOS_HEADER_SIZE+46); /* count of bytes to read */
 
 	ASSERT( result <= count );
 
-	LOG(("read %ld bytes (should be < %ld)\n", result, count));
+	D(("read %ld bytes (should be < %ld)", result, count));
 
  out:
 
@@ -1686,7 +1686,7 @@ smb_proc_read_raw (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 	}
 
 	return result;
@@ -1727,7 +1727,7 @@ smb_proc_write (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 	}
 	else
 	{
@@ -1755,7 +1755,7 @@ smb_proc_write_raw (
 
 	ASSERT( count <= 65535 );
 
-	LOG (("number of bytes to send = %ld\n", count));
+	D(("number of bytes to send = %ld", count));
 
 	/* Calculate the maximum number of bytes that could be transferred with
 	 * a single SMB_COM_WRITE_RAW packet...
@@ -1786,7 +1786,7 @@ smb_proc_write_raw (
 
 	max_len -= 63;
 
-	LOG(("maximum length for payload = %ld bytes\n", max_len));
+	D(("maximum length for payload = %ld bytes", max_len));
 
 	/* Number of bytes to write is smaller than the maximum
 	 * number of bytes which may be sent in a single SMB
@@ -1794,7 +1794,7 @@ smb_proc_write_raw (
 	 */
 	if (count <= max_len)
 	{
-		LOG(("count (%ld) <= max_len (%ld) -- send no data with the message.\n",count,max_len));
+		D(("count (%ld) <= max_len (%ld) -- send no data with the message.",count,max_len));
 
 		len = 0; /* Send a zero length SMB_COM_WRITE_RAW message, followed by the raw data. */
 	}
@@ -1802,7 +1802,7 @@ smb_proc_write_raw (
 	{
 		len = count - max_len; /* Send some of the data as part of the SMB_COM_WRITE_RAW message, followed by the remaining raw data. */
 
-		LOG(("count (%ld) > max_len (%ld) -- send %ld bytes with the message.\n",count,max_len,len));
+		D(("count (%ld) > max_len (%ld) -- send %ld bytes with the message.",count,max_len,len));
 	}
 
  retry:
@@ -1826,7 +1826,7 @@ smb_proc_write_raw (
 	WSET (buf, smb_vwv11, p - smb_base(buf));
 	DSET (buf, smb_vwv12, offset_quad->High);
 
-	LOG(("requesting SMBwritebraw\n"));
+	SHOWMSG("requesting SMBwritebraw");
 
 	result = smb_request_ok_with_payload (server, SMBwritebraw, 1, 0, NULL, data, len, error_ptr);
 	if (result < 0)
@@ -1837,7 +1837,7 @@ smb_proc_write_raw (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 		goto out;
 	}
 
@@ -1846,11 +1846,11 @@ smb_proc_write_raw (
 	data += len;
 	count -= len;
 
-	LOG (("bytes sent so far = %ld\n", num_bytes_written));
+	D(("bytes sent so far = %ld", num_bytes_written));
 
 	if(count > 0)
 	{
-		LOG(("sending %ld bytes of data (raw)\n",count));
+		D(("sending %ld bytes of data (raw)",count));
 
 		ASSERT( count <= 65535 );
 
@@ -1869,7 +1869,7 @@ smb_proc_write_raw (
 					goto retry;
 			}
 
-			LOG(("that didn't work.\n"));
+			SHOWMSG("that didn't work.");
 			goto out;
 		}
 
@@ -1887,7 +1887,7 @@ smb_proc_write_raw (
 			/* We have to do the checks of smb_request_ok here as well */
 			if ((error = smb_valid_packet (server->transmit_buffer)) != 0)
 			{
-				LOG (("not a valid packet!\n"));
+				SHOWMSG("not a valid packet!");
 
 				(*error_ptr) = error;
 				result = -1;
@@ -1896,7 +1896,7 @@ smb_proc_write_raw (
 			}
 			else if (server->rcls != 0)
 			{
-				LOG (("server error %ld/%ld\n", server->rcls, server->err));
+				D(("server error %ld/%ld", server->rcls, server->err));
 
 				smb_printerr (server->rcls, server->err);
 
@@ -1909,7 +1909,7 @@ smb_proc_write_raw (
 			num_bytes_written += count;
 		}
 
-		LOG (("bytes sent so far = %ld\n", num_bytes_written));
+		D(("bytes sent so far = %ld", num_bytes_written));
 	}
 
 	result = num_bytes_written;
@@ -1934,7 +1934,7 @@ smb_proc_writex (
 
 	ASSERT( count <= 65535 );
 
-	LOG (("number of bytes to send = %ld\n", count));
+	D(("number of bytes to send = %ld", count));
 
  retry:
 
@@ -1965,7 +1965,7 @@ smb_proc_writex (
 	WSET (p, 0, 1+count); p += 2; /* Byte count (1 pad byte + data bytes)  */
 	(*p) = 0; /* Padding byte that must be ignored */
 
-	LOG(("requesting SMBwriteX: offset=%s, count=%ld\n", convert_quad_to_string(offset_quad), count));
+	D(("requesting SMBwriteX: offset=%s, count=%ld", convert_quad_to_string(offset_quad), count));
 
 	result = smb_request_ok_with_payload (server, SMBwriteX, 6, 0, NULL, data, count, error_ptr);
 	if (result < 0)
@@ -1976,7 +1976,7 @@ smb_proc_writex (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 	}
 	else
 	{
@@ -1985,7 +1985,7 @@ smb_proc_writex (
 		p = SMB_VWV (server->transmit_buffer);
 		smb_decode_word (p + 4, &available);
 
-		LOG(("number of bytes written = %ld\n", available));
+		D(("number of bytes written = %ld", available));
 
 		result = available;
 	}
@@ -2008,7 +2008,7 @@ smb_proc_readx (
 
 	ASSERT( count <= 65535 );
 
-	LOG (("number of bytes to read = %ld\n", count));
+	D(("number of bytes to read = %ld", count));
 
  retry:
 
@@ -2030,7 +2030,7 @@ smb_proc_readx (
 
 	WSET (p, 0, 0); /* Byte count */
 
-	LOG(("requesting SMBreadX: offset=%s, count=%ld\n", convert_quad_to_string(offset_quad), count));
+	D(("requesting SMBreadX: offset=%s, count=%ld", convert_quad_to_string(offset_quad), count));
 
 	result = smb_request_ok_with_payload (server, SMBreadX, 7, 0, data, NULL, count, error_ptr);
 	if (result < 0)
@@ -2041,7 +2041,7 @@ smb_proc_readx (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 	}
 	else
 	{
@@ -2050,7 +2050,7 @@ smb_proc_readx (
 		p = SMB_VWV (server->transmit_buffer);
 		smb_decode_word (p + 10, &data_length);
 
-		LOG(("number of bytes read = %ld\n", data_length));
+		D(("number of bytes read = %ld", data_length));
 
 		result = data_length;
 	}
@@ -2113,7 +2113,7 @@ smb_proc_lockingX (
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 	}
 
 	return result;
@@ -2138,7 +2138,7 @@ smb_proc_create (struct smb_server *server, const char *path, int len, struct sm
 
 		seconds_to_tm(entry->ctime,&tm_utc);
 
-		LOG(("creation time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+		D(("creation time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 			tm_utc.tm_year + 1900,
 			tm_utc.tm_mon+1,
 			tm_utc.tm_mday,
@@ -2148,7 +2148,7 @@ smb_proc_create (struct smb_server *server, const char *path, int len, struct sm
 
 		seconds_to_tm(local_time,&tm_local);
 
-		LOG(("                %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+		D(("                %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 			tm_local.tm_year + 1900,
 			tm_local.tm_mon+1,
 			tm_local.tm_mday,
@@ -2456,7 +2456,7 @@ smb_decode_short_dirent (dircache_t * dircache, const char *p, struct smb_dirent
 
 	entry->complete_path[name_len] = '\0';
 
-	LOG (("name = '%s'\n", escape_name(entry->complete_path)));
+	D(("name = '%s'", escape_name(entry->complete_path)));
 
 	#if DEBUG
 	{
@@ -2464,7 +2464,7 @@ smb_decode_short_dirent (dircache_t * dircache, const char *p, struct smb_dirent
 
 		seconds_to_tm(entry->mtime,&tm);
 
-		LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",
+		D(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",
 			tm.tm_year + 1900,
 			tm.tm_mon+1,
 			tm.tm_mday,
@@ -2482,7 +2482,6 @@ static int
 smb_proc_readdir_short (
 	struct smb_server *server,
 	const char *path,
-	int fpos,
 	dircache_t * dircache,
 	int * end_of_search_ptr,
 	int * error_ptr)
@@ -2522,8 +2521,8 @@ smb_proc_readdir_short (
 	else
 		mask_size = 1 + mask_len+1 + 3;
 
-	LOG (("SMB call readdir @ %ld\n", fpos));
-	LOG (("                 mask = '%s'\n", escape_name(mask)));
+	SHOWMSG("SMB call readdir_short");
+	D(("         mask = '%s'", escape_name(mask)));
 
 	buf = server->transmit_buffer;
 
@@ -2535,7 +2534,7 @@ smb_proc_readdir_short (
 	{
 		is_first = TRUE;
 
-		LOG (("start scanning from the top (fpos=%ld)\n", fpos));
+		SHOWMSG("start scanning from the top");
 	}
 	else
 	{
@@ -2548,13 +2547,13 @@ smb_proc_readdir_short (
 
 	entry = get_first_dircache_entry(dircache);
 
-	while (entry != NULL && dircache->is_valid)
+	while (entry != NULL)
 	{
 		entries_asked = get_dircache_entries_available(dircache);
 
 		if (is_first)
 		{
-			LOG(("reading first directory entries\n"));
+			SHOWMSG("reading first directory entries");
 
 			ASSERT( smb_payload_size(server, 2, mask_size) >= 0 );
 
@@ -2581,7 +2580,7 @@ smb_proc_readdir_short (
 		{
 			int size;
 
-			LOG(("reading next directory entries\n"));
+			SHOWMSG("reading next directory entries");
 
 			if(server->unicode_enabled)
 				size = 1 + 2 * (1) + 3 + SMB_RESUME_KEY_SIZE;
@@ -2613,7 +2612,7 @@ smb_proc_readdir_short (
 		{
 			if (server->rcls == ERRDOS && server->err == ERRnofiles)
 			{
-				LOG(("not resuming this scan operation\n"));
+				SHOWMSG("not resuming this scan operation");
 
 				end_of_search = TRUE;
 
@@ -2624,7 +2623,7 @@ smb_proc_readdir_short (
 
 			if ((*error_ptr) != error_check_smb_error && smb_retry (server))
 			{
-				LOG(("retrying...\n"));
+				SHOWMSG("retrying...");
 
 				goto retry;
 			}
@@ -2639,16 +2638,16 @@ smb_proc_readdir_short (
 
 		p = smb_decode_word (p, &bcc);
 
-		LOG(("number of directory entries returned = %ld\n", count));
+		D(("number of directory entries returned = %ld", count));
 
-		if (count <= 0)
+		if (count == 0)
 			break;
 
 		ASSERT (bcc == count * SMB_DIRINFO_SIZE + 3);
 
 		if (bcc != count * SMB_DIRINFO_SIZE + 3)
 		{
-			LOG (("byte count (%ld) does not match expected size (%ld)\n", bcc, count * SMB_DIRINFO_SIZE + 3));
+			D(("byte count (%ld) does not match expected size (%ld)", bcc, count * SMB_DIRINFO_SIZE + 3));
 
 			(*error_ptr) = error_invalid_directory_size;
 
@@ -2657,7 +2656,7 @@ smb_proc_readdir_short (
 
 		if((*p++) != 5)
 		{
-			LOG (("buffer format mismatch (should be 5, is %ld)\n", p[-1]));
+			D(("buffer format mismatch (should be 5, is %ld)", p[-1]));
 
 			(*error_ptr) = error_invalid_directory_size;
 
@@ -2668,7 +2667,7 @@ smb_proc_readdir_short (
 
 		if(datalength != 43 * count)
 		{
-			LOG (("data length (%ld) does not match expected size (%ld)\n", datalength, count * SMB_DIRINFO_SIZE));
+			D(("data length (%ld) does not match expected size (%ld)", datalength, count * SMB_DIRINFO_SIZE));
 
 			(*error_ptr) = error_invalid_directory_size;
 
@@ -2676,20 +2675,14 @@ smb_proc_readdir_short (
 		}
 
 		/* Now we are ready to parse smb directory entries. */
-		for (i = 0; i < count; i++)
+		for (i = 0; entry != NULL && i < count; i++)
 		{
-			/* Was the cache invalidated, or there are no further
-			 * cache entries to be filled?
-			 */
-			if (entry == NULL || !dircache->is_valid)
-				break;
-
 			smb_decode_short_dirent (dircache, p, entry);
 			p += SMB_DIRINFO_SIZE;
 
 			entry = get_next_dircache_entry(dircache);
 
-			total_count += 1;
+			total_count++;
 		}
 
 		ASSERT( sizeof(dircache->search_resume_key) >= SMB_RESUME_KEY_SIZE );
@@ -2707,14 +2700,14 @@ smb_proc_readdir_short (
 
 	if(result == -1)
 	{
-		LOG(("not resuming this scan operation\n"));
+		SHOWMSG("not resuming this scan operation");
 
 		dircache->sid = -1;
 	}
 
 	(*end_of_search_ptr) = end_of_search;
 
-	LOG(("number of entries read = %ld", result));
+	D(("number of entries read = %ld", result));
 
 	return result;
 }
@@ -2843,7 +2836,7 @@ smb_decode_long_dirent (
 				/* Skip directory entries whose names we cannot store. */
 				if(name_len >= (int)finfo->complete_path_size)
 				{
-					LOG(("name length >= %lu (skipping it)\n", (unsigned long)finfo->complete_path_size));
+					D(("name length >= %lu (skipping it)", (unsigned long)finfo->complete_path_size));
 
 					success = FALSE;
 					break;
@@ -2851,7 +2844,7 @@ smb_decode_long_dirent (
 
 				if(name_len == 0)
 				{
-					LOG(("name length == 0 (skipping it)\n"));
+					SHOWMSG("name length == 0 (skipping it)");
 
 					success = FALSE;
 					break;
@@ -2877,20 +2870,20 @@ smb_decode_long_dirent (
 
 				finfo->len = name_len;
 
-				LOG(("name = '%s', length=%ld, size=%ld\n",escape_name(finfo->complete_path),name_len,name_size));
+				D(("name = '%s', length=%ld, size=%ld",escape_name(finfo->complete_path),name_len,name_size));
 
 				#if DEBUG
 				{
 					struct tm tm;
 
 					seconds_to_tm(finfo->mtime,&tm);
-					LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->ctime,&tm);
-					LOG(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->atime,&tm);
-					LOG(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->wtime,&tm);
-					LOG(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 				}
 				#endif /* DEBUG */
 			}
@@ -2977,7 +2970,7 @@ smb_decode_long_dirent (
 				/* Skip directory entries whose names we cannot store. */
 				if(name_len >= (int)finfo->complete_path_size)
 				{
-					LOG(("name length >= %lu (skipping it)\n", (unsigned long)finfo->complete_path_size));
+					D(("name length >= %lu (skipping it)", (unsigned long)finfo->complete_path_size));
 
 					success = FALSE;
 					break;
@@ -2985,7 +2978,7 @@ smb_decode_long_dirent (
 
 				if(name_len == 0)
 				{
-					LOG(("name length == 0 (skipping it)\n"));
+					SHOWMSG("name length == 0 (skipping it)");
 
 					success = FALSE;
 					break;
@@ -3003,20 +2996,20 @@ smb_decode_long_dirent (
 
 				finfo->len = name_len;
 
-				LOG(("name = '%s', length=%ld, size=%ld\n",escape_name(finfo->complete_path),name_len,name_size));
+				D(("name = '%s', length=%ld, size=%ld",escape_name(finfo->complete_path),name_len,name_size));
 
 				#if DEBUG
 				{
 					struct tm tm;
 
 					seconds_to_tm(finfo->mtime,&tm);
-					LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->ctime,&tm);
-					LOG(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->atime,&tm);
-					LOG(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 					seconds_to_tm(finfo->wtime,&tm);
-					LOG(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+					D(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 				}
 				#endif /* DEBUG */
 			}
@@ -3032,7 +3025,7 @@ smb_decode_long_dirent (
 			break;
 	}
 
-	LOG(("entry_length = %ld\n",(*entry_length_ptr)));
+	D(("entry_length = %ld",(*entry_length_ptr)));
 
 	RETURN(success);
 	return(success);
@@ -3042,7 +3035,6 @@ static int
 smb_proc_readdir_long (
 	struct smb_server *server,
 	const char *path,
-	int fpos,
 	dircache_t * dircache,
 	int * end_of_search_ptr,
 	int * error_ptr)
@@ -3086,7 +3078,7 @@ smb_proc_readdir_long (
 	pattern = malloc (pattern_len+1);
 	if (pattern == NULL)
 	{
-		LOG (("Memory allocation failed\n"));
+		SHOWMSG("Memory allocation failed");
 
 		(*error_ptr) = ENOMEM;
 
@@ -3097,8 +3089,8 @@ smb_proc_readdir_long (
 	memcpy(pattern,path,path_len);
 	memcpy(&pattern[path_len],"\\*",3); /* This includes the terminating NUL. */
 
-	LOG (("SMB call lreaddir @ %ld\n", fpos));
-	LOG (("                  pattern = '%s'\n", escape_name(pattern)));
+	SHOWMSG("SMB call readdir_long");
+	D(("         pattern = '%s'", escape_name(pattern)));
 
 	resp_param = NULL;
 	resp_data = NULL;
@@ -3107,7 +3099,7 @@ smb_proc_readdir_long (
 	{
 		int sid = dircache->close_sid;
 
-		LOG(("closing previous find-first/find-next session with sid=0x%04lx\n", sid));
+		D(("closing previous find-first/find-next session with sid=0x%04lx", sid));
 
 		dircache->close_sid = -1;
 
@@ -3123,7 +3115,7 @@ smb_proc_readdir_long (
 	{
 		is_first = TRUE;
 
-		LOG (("start scanning from the top (fpos=%ld)\n", fpos));
+		SHOWMSG("start scanning from the top");
 	}
 	else
 	{
@@ -3132,10 +3124,11 @@ smb_proc_readdir_long (
 		ff_dir_handle = dircache->sid;
 		ff_resume_key = dircache->resume_key;
 
-		LOG (("trying to resume scanning with sid=0x%04lx and resume_key=0x%08lx\n", ff_dir_handle, ff_resume_key));
+		D(("trying to resume scanning with sid=0x%04lx and resume_key=0x%08lx", ff_dir_handle, ff_resume_key));
 	}
 
 	total_count = 0;
+	ff_end_of_search = 0;
 
 	entry = get_first_dircache_entry(dircache);
 
@@ -3143,12 +3136,12 @@ smb_proc_readdir_long (
 	{
 		if (++loop_count > 200)
 		{
-			LOG (("Looping in FIND_NEXT???\n"));
+			SHOWMSG("Looping in FIND_NEXT???");
 
 			(*error_ptr) = error_looping_in_find_next;
 
 			result = -1;
-			break;
+			goto out;
 		}
 
 		memset (outbuf, 0, sizeof(word) * smb_setup1);
@@ -3181,11 +3174,13 @@ smb_proc_readdir_long (
 
 		max_matches = get_dircache_entries_available(dircache);
 
-		LOG(("max_matches=%ld\n", max_matches));
+		ASSERT( max_matches > 0 );
 
-		if (is_first || ff_dir_handle == -1)
+		D(("max_matches=%ld", max_matches));
+
+		if (is_first)
 		{
-			LOG (("first match\n"));
+			SHOWMSG("first match");
 
 			WSET (p, 0, attribute); /* attribute */
 			WSET (p, 2, max_matches); /* max count */
@@ -3195,7 +3190,7 @@ smb_proc_readdir_long (
 		}
 		else
 		{
-			LOG (("next match; ff_dir_handle=0x%04lx ff_resume_key=0x%08lx pattern='%s'\n", ff_dir_handle, ff_resume_key, escape_name(pattern)));
+			D(("next match; ff_dir_handle=0x%04lx ff_resume_key=0x%08lx pattern='%s'", ff_dir_handle, ff_resume_key, escape_name(pattern)));
 
 			WSET (p, 0, ff_dir_handle);
 			WSET (p, 2, max_matches); /* max count */
@@ -3218,7 +3213,7 @@ smb_proc_readdir_long (
 
 		result = smb_trans2_request (server, SMBtrans2, &resp_data_len, &resp_param_len, &resp_data, &resp_param, error_ptr);
 
-		LOG (("smb_trans2_request returns %ld\n", result));
+		D(("smb_trans2_request returns %ld", result));
 
 		/* If an error was flagged, check first if it's a protocol
 		 * error which we could handle below. Otherwise, try again.
@@ -3228,8 +3223,8 @@ smb_proc_readdir_long (
 			if (smb_retry (server))
 				goto retry;
 
-			LOG (("got error from trans2_request\n"));
-			break;
+			SHOWMSG("got error from trans2_request");
+			goto out;
 		}
 
 		/* Apparently, there is a bug in Windows 95 and friends which
@@ -3252,20 +3247,20 @@ smb_proc_readdir_long (
 		/* If there's a protocol error, stop and abort. */
 		if (server->rcls != 0)
 		{
-			LOG (("server->rcls = %ld err = %ld\n",server->rcls, server->err));
+			D(("server->rcls = %ld err = %ld",server->rcls, server->err));
 
 			smb_printerr (server->rcls, server->err);
 
 			(*error_ptr) = error_check_smb_error;
 
 			result = -1;
-			break;
+			goto out;
 		}
 
 		/* Bail out if this is empty. */
 		if (resp_param == NULL)
 		{
-			LOG(("no response parameters to process; stopping the search for now\n"));
+			SHOWMSG("no response parameters to process; stopping the search for now");
 			break;
 		}
 
@@ -3276,7 +3271,7 @@ smb_proc_readdir_long (
 		{
 			if(resp_param_len < 6)
 			{
-				LOG(("not enough response parameter data to process; stopping the search for now\n"));
+				SHOWMSG("not enough response parameter data to process; stopping the search for now");
 				break;
 			}
 
@@ -3293,7 +3288,7 @@ smb_proc_readdir_long (
 		{
 			if(resp_param_len < 4)
 			{
-				LOG(("not enough response parameter data to process; stopping the search for now\n"));
+				SHOWMSG("not enough response parameter data to process; stopping the search for now");
 				break;
 			}
 
@@ -3301,18 +3296,18 @@ smb_proc_readdir_long (
 			ff_end_of_search = WVAL (p, 2);
 		}
 
-		LOG (("received %ld entries (end of search = %s)\n",ff_searchcount, ff_end_of_search ? "yes" : "no"));
+		D(("received %ld entries (end of search = %s)",ff_searchcount, ff_end_of_search ? "yes" : "no"));
 
 		if (ff_searchcount == 0)
 		{
-			LOG(("no further entries available; stopping the search for now\n"));
+			SHOWMSG("no further entries available; stopping the search for now");
 			break;
 		}
 
 		/* Bail out if this is empty. */
 		if (resp_data == NULL)
 		{
-			LOG(("no directory data to process; stopping the search for now\n"));
+			SHOWMSG("no directory data to process; stopping the search for now");
 			break;
 		}
 
@@ -3321,12 +3316,12 @@ smb_proc_readdir_long (
 
 		/* Now we are ready to parse smb directory entries. */
 		for (i = 0, entry_length = 0 ;
-		     i < ff_searchcount && entry != NULL && dircache->is_valid && p < &resp_data[resp_data_len];
+		     i < ff_searchcount && entry != NULL && p < &resp_data[resp_data_len];
 		     i++, p += entry_length)
 		{
 			ff_resume_key = DVAL(p, 0);
 
-			LOG(("sid=0x%04lx, resume_key=0x%08lx\n", ff_dir_handle, ff_resume_key));
+			D(("sid=0x%04lx, resume_key=0x%08lx", ff_dir_handle, ff_resume_key));
 
 			/* Skip this entry if we cannot decode the name. This could happen
 			 * if the name will no fit into the buffer.
@@ -3335,18 +3330,18 @@ smb_proc_readdir_long (
 			{
 				if(entry_length == 0)
 				{
-					LOG (("no more entries available; stopping.\n"));
+					SHOWMSG("no more entries available; stopping.");
 					break;
 				}
 
-				LOG (("skipped entry; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
+				D(("skipped entry; total_count = %ld, i = %ld", total_count, i));
 
 				continue;
 			}
 
 			entry = get_next_dircache_entry(dircache);
 
-			total_count += 1;
+			total_count++;
 		}
 
 		if (resp_data != NULL)
@@ -3367,6 +3362,8 @@ smb_proc_readdir_long (
 			loop_count = 0;
 	}
 
+	result = total_count;
+
  out:
 
 	/* finished: not needed any more */
@@ -3381,11 +3378,11 @@ smb_proc_readdir_long (
 
 	(*end_of_search_ptr) = ff_end_of_search;
 
-	if(result == 0)
+	if(result >= 0)
 	{
 		if(ff_end_of_search)
 		{
-			LOG(("not resuming this scan operation\n"));
+			SHOWMSG("not resuming this scan operation");
 
 			dircache->sid = -1;
 			dircache->resume_key = 0;
@@ -3395,12 +3392,10 @@ smb_proc_readdir_long (
 			dircache->sid = ff_dir_handle;
 			dircache->resume_key = ff_resume_key;
 		}
-
-		result = total_count;
 	}
 	else
 	{
-		LOG(("not resuming this scan operation\n"));
+		SHOWMSG("not resuming this scan operation");
 
 		dircache->sid = -1;
 		dircache->resume_key = 0;
@@ -3414,7 +3409,6 @@ int
 smb_proc_readdir (
 	struct smb_server *server,
 	const char *path,
-	int fpos,
 	dircache_t * dircache,
 	int * end_of_search_ptr,
 	int * error_ptr)
@@ -3422,9 +3416,9 @@ smb_proc_readdir (
 	int result;
 
 	if (server->protocol >= PROTOCOL_LANMAN2)
-		result = smb_proc_readdir_long (server, path, fpos, dircache, end_of_search_ptr, error_ptr);
+		result = smb_proc_readdir_long (server, path, dircache, end_of_search_ptr, error_ptr);
 	else
-		result = smb_proc_readdir_short (server, path, fpos, dircache, end_of_search_ptr, error_ptr);
+		result = smb_proc_readdir_short (server, path, dircache, end_of_search_ptr, error_ptr);
 
 	return result;
 }
@@ -3437,7 +3431,7 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
 	char *buf = server->transmit_buffer;
 	int path_size;
 
-	LOG (("path='%s'\n", escape_name(path)));
+	D(("path='%s'", escape_name(path)));
 
 	if(server->unicode_enabled)
 		path_size = 1 + 2 * (len + 1);
@@ -3481,7 +3475,7 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
 
 		seconds_to_tm(entry->mtime,&tm_utc);
 
-		LOG(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+		D(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 			tm_utc.tm_year + 1900,
 			tm_utc.tm_mon+1,
 			tm_utc.tm_mday,
@@ -3491,7 +3485,7 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
 
 		seconds_to_tm(DVAL (buf, smb_vwv1),&tm_local);
 
-		LOG(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+		D(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 			tm_local.tm_year + 1900,
 			tm_local.tm_mon+1,
 			tm_local.tm_mday,
@@ -3687,16 +3681,16 @@ smb_query_path_information(
 		entry_size_quad.High	= entry->size_high;
 
 		seconds_to_tm(entry->mtime,&tm);
-		LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 		seconds_to_tm(entry->ctime,&tm);
-		LOG(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 		seconds_to_tm(entry->atime,&tm);
-		LOG(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 		seconds_to_tm(entry->wtime,&tm);
-		LOG(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
-		LOG(("size = %s (0x%08lx%08lx)\n",convert_quad_to_string(&entry_size_quad),entry->size_high,entry->size_low));
-		LOG(("attr = 0x%08lx\n",entry->attr));
-		LOG(("name = '%s' (length in bytes = %ld)\n",escape_name(name),file_name_length));
+		D(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("size = %s (0x%08lx%08lx)",convert_quad_to_string(&entry_size_quad),entry->size_high,entry->size_low));
+		D(("attr = 0x%08lx",entry->attr));
+		D(("name = '%s' (length in bytes = %ld)",escape_name(name),file_name_length));
 	}
 	#endif /* DEBUG */
 
@@ -3744,16 +3738,16 @@ smb_proc_getattrE (struct smb_server *server, struct smb_dirent *entry, int * er
 		struct tm tm;
 
 		seconds_to_tm(entry->ctime,&tm);
-		LOG(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("ctime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 
 		seconds_to_tm(entry->atime,&tm);
-		LOG(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("atime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 
 		seconds_to_tm(entry->mtime,&tm);
-		LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 
 		seconds_to_tm(entry->wtime,&tm);
-		LOG(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
+		D(("wtime = %ld-%02ld-%02ld %ld:%02ld:%02ld",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
 	}
 	#endif /* DEBUG */
 
@@ -3829,7 +3823,7 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
 		 * even if the wtime value is given as zero and the
 		 * mtime value is non-zero.
 		 */
-		LOG(("entry->mtime = %lu\n",entry->mtime));
+		D(("entry->mtime = %lu",entry->mtime));
 
 		convert_time_t_to_long_date(entry->mtime,&change_time_quad);
 
@@ -3863,7 +3857,7 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
 				goto retry;
 		}
 
-		LOG(("that didn't work.\n"));
+		SHOWMSG("that didn't work.");
 		goto out;
 	}
 
@@ -3918,7 +3912,7 @@ smb_proc_setattr_core (struct smb_server *server, const char *path, int len, con
 
 		seconds_to_tm(new_finfo->mtime,&tm_utc);
 
-		LOG(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)\n",
+		D(("modification time = %ld-%02ld-%02ld %02ld:%02ld:%02ld (UTC)",
 			tm_utc.tm_year + 1900,
 			tm_utc.tm_mon+1,
 			tm_utc.tm_mday,
@@ -3928,7 +3922,7 @@ smb_proc_setattr_core (struct smb_server *server, const char *path, int len, con
 
 		seconds_to_tm(local_time,&tm_local);
 
-		LOG(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)\n",
+		D(("                    %ld-%02ld-%02ld %02ld:%02ld:%02ld (local)",
 			tm_local.tm_year + 1900,
 			tm_local.tm_mon+1,
 			tm_local.tm_mday,
@@ -4048,7 +4042,7 @@ smb_proc_setattrE (struct smb_server *server, word fid, struct smb_dirent *new_e
 				}
 			}
 
-			LOG(("that didn't work.\n"));
+			SHOWMSG("that didn't work.");
 		}
 	}
 	else
@@ -4255,7 +4249,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	result = smb_connect (server, error_ptr);
 	if (result < 0)
 	{
-		LOG (("could not connect to server\n"));
+		SHOWMSG("could not connect to server");
 		goto out;
 	}
 
@@ -4309,7 +4303,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	server->transmit_buffer = malloc (server->transmit_buffer_allocation_size);
 	if (server->transmit_buffer == NULL)
 	{
-		LOG (("No memory! Bailing out.\n"));
+		SHOWMSG("No memory! Bailing out.");
 
 		(*error_ptr) = ENOMEM;
 
@@ -4338,13 +4332,13 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		result = smb_request (server, 0, NULL, NULL, 0, error_ptr);
 		if (result < 0)
 		{
-			LOG (("Failed to send SESSION REQUEST.\n"));
+			SHOWMSG("Failed to send SESSION REQUEST.");
 			goto out;
 		}
 
 		if (packet[0] != 0x82)
 		{
-			LOG (("Did not receive positive response (err = %lx)\n",packet[0]));
+			D(("Did not receive positive response (err = %lx)",packet[0]));
 
 			#if DEBUG
 			{
@@ -4358,7 +4352,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 			goto out;
 		}
 
-		LOG (("Passed SESSION REQUEST.\n"));
+		SHOWMSG("Passed SESSION REQUEST.");
 	}
 
 	/* Now we are ready to send a SMB Negotiate Protocol packet. */
@@ -4375,12 +4369,12 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	for (i = 0; i < num_prots ; i++)
 		p = smb_encode_dialect (p, prots[i].name, strlen (prots[i].name));
 
-	LOG (("Request SMBnegprot...\n"));
+	SHOWMSG("Request SMBnegprot...");
 
 	result = smb_request_ok (server, SMBnegprot, 1, -1, error_ptr);
 	if (result < 0)
 	{
-		LOG (("Failure requesting SMBnegprot\n"));
+		SHOWMSG("Failure requesting SMBnegprot");
 		goto out;
 	}
 
@@ -4393,7 +4387,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	 */
 	if(dialect_index > num_prots || dialect_index == 0xFFFFU)
 	{
-		LOG (("Unsupported dialect\n"));
+		SHOWMSG("Unsupported dialect");
 
 		(*error_ptr) = error_unsupported_dialect;
 
@@ -4403,7 +4397,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 
 	server->protocol = prots[dialect_index].prot;
 
-	LOG (("Server wants %s protocol.\n",prots[dialect_index].name));
+	D(("Server wants %s protocol.",prots[dialect_index].name));
 
 	if (server->protocol > PROTOCOL_LANMAN1)
 	{
@@ -4411,10 +4405,10 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		dword server_sesskey;
 
 		/*
-		LOG (("password = %s\n",server->mount_data.password));
+		D(("password = %s",server->mount_data.password));
 		*/
-		LOG (("usernam = %s\n",server->mount_data.username));
-		LOG (("blkmode = %ld\n",WVAL (packet, smb_vwv5)));
+		D(("usernam = %s",server->mount_data.username));
+		D(("blkmode = %ld",WVAL (packet, smb_vwv5)));
 
 		/* NT LAN Manager or newer. */
 		if (server->protocol >= PROTOCOL_NT1)
@@ -4528,7 +4522,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		SHOWVALUE(oem_password_len);
 		SHOWVALUE(unicode_password_len);
 
-		LOG (("workgroup = %s\n", server->mount_data.workgroup_name));
+		D(("workgroup = %s", server->mount_data.workgroup_name));
 
 		/* NT LAN Manager or newer. */
 		if (server->protocol >= PROTOCOL_NT1)
@@ -4744,7 +4738,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		result = smb_request_ok (server, SMBsesssetupX, 3, 0, error_ptr);
 		if (result < 0)
 		{
-			LOG (("SMBsessetupX failed\n"));
+			SHOWMSG("SMBsessetupX fail");
 			goto out;
 		}
 
@@ -4784,7 +4778,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		share_name = malloc(share_name_len+1);
 		if(share_name == NULL)
 		{
-			LOG (("No memory! Bailing out.\n"));
+			SHOWMSG("No memory! Bailing out.");
 
 			(*error_ptr) = ENOMEM;
 
@@ -4806,7 +4800,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 
 		string_toupper(share_name);
 
-		LOG(("share_name = '%s'\n", escape_name(share_name)));
+		D(("share_name = '%s'", escape_name(share_name)));
 
 		if(server->unicode_enabled)
 			share_name_size = 2 * (share_name_len + 1);
@@ -4849,7 +4843,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		{
 			SHOWVALUE(SMB_WCT(packet));
 
-			LOG (("SMBtconX not verified.\n"));
+			SHOWMSG("SMBtconX not verifie");
 			goto out;
 		}
 
@@ -4878,11 +4872,11 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		result = smb_request_ok (server, SMBtcon, 2, 0, error_ptr);
 		if (result < 0)
 		{
-			LOG (("SMBtcon not verified.\n"));
+			SHOWMSG("SMBtcon not verified.");
 			goto out;
 		}
 
-		LOG (("OK! Managed to set up SMBtcon!\n"));
+		SHOWMSG("OK! Managed to set up SMBtcon!");
 
 		p = SMB_VWV (packet);
 		p = smb_decode_word (p, &decoded_max_xmit);
@@ -4898,7 +4892,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		(void) smb_decode_word (p, &server->tid);
 	}
 
-	LOG (("max_buffer_size = %ld, tid = %ld\n", max_buffer_size, server->tid));
+	D(("max_buffer_size = %ld, tid = %ld", max_buffer_size, server->tid));
 
 	/* Let's get paranoid. Make sure that we can actually receive
 	 * as much data as the buffer size allows, in a single consecutive
@@ -4911,7 +4905,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		/* We need to allocate a larger packet buffer. */
 		packet_size = max_buffer_size;
 
-		LOG(("packet size updated to %ld bytes\n", packet_size));
+		D(("packet size updated to %ld bytes", packet_size));
 
 		free (server->transmit_buffer);
 
@@ -4925,7 +4919,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 		server->transmit_buffer = malloc (server->transmit_buffer_allocation_size);
 		if (server->transmit_buffer == NULL)
 		{
-			LOG (("No memory! Bailing out.\n"));
+			SHOWMSG("No memory! Bailing out.");
 
 			(*error_ptr) = ENOMEM;
 
@@ -4940,7 +4934,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	if(8000 <= server->mount_data.given_max_xmit && server->mount_data.given_max_xmit < (int)max_buffer_size)
 	{
 		max_buffer_size = server->mount_data.given_max_xmit;
-		LOG(("maximum buffer size limited to %ld bytes\n", max_buffer_size));
+		D(("maximum buffer size limited to %ld bytes", max_buffer_size));
 	}
 
 	server->max_buffer_size = max_buffer_size;
@@ -4952,7 +4946,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
 	if(enable_unicode)
 		server->unicode_enabled = TRUE;
 
-	LOG (("Normal exit\n"));
+	SHOWMSG("Normal exit");
 
 	result = 0;
 
@@ -5001,7 +4995,7 @@ smb_printerr (int class, int num)
 		{
 			report_error("%s - %ld.", err_classes[i].class, num);
 
-			LOG (("%s - %ld\n", err_classes[i].class, num));
+			D(("%s - %ld", err_classes[i].class, num));
 			return;
 		}
 
@@ -5014,12 +5008,12 @@ smb_printerr (int class, int num)
 
 			report_error ("%s - %s (%s).", err_classes[i].class, err[j].name, err[j].message);
 
-			LOG (("%s - %s (%s)\n", err_classes[i].class, err[j].name, err[j].message));
+			D(("%s - %s (%s)", err_classes[i].class, err[j].name, err[j].message));
 			return;
 		}
 	}
 
 	report_error ("Unknown error - (%ld, %ld).", class, num);
 
-	LOG (("Unknown error - (%ld, %ld)\n", class, num));
+	D(("Unknown error - (%ld, %ld)", class, num));
 }
diff --git a/source_code/smb_abstraction.c b/source_code/smb_abstraction.c
index d5beb86..43f4776 100644
--- a/source_code/smb_abstraction.c
+++ b/source_code/smb_abstraction.c
@@ -22,10 +22,13 @@
 
 /*****************************************************************************/
 
-#define ATTR_CACHE_TIME	5	/* cache attributes for this time (seconds) */
-#define DIR_CACHE_TIME	10	/* cache directories for this time (seconds) */
-#define DIRCACHE_SIZE	170
-#define DOS_PATHSEP		'\\'
+/* File attributes will have to be refreshed after this many
+ * seconds have passed since the last update.
+ */
+#define ATTR_CACHE_TIME	5
+
+/* Default number of entries in the directory cache. */
+#define DIRCACHE_SIZE 170
 
 /*****************************************************************************/
 
@@ -33,27 +36,14 @@
 
 /*****************************************************************************/
 
-static int
-dircache_is_stale(ULONG now, int expires, const dircache_t * dircache)
-{
-	int result;
-
-	ASSERT( dircache != NULL );
-
-	result = (now > dircache->created_at && (now - dircache->created_at) > expires);
-
-	return(result);
-}
-
-/*****************************************************************************/
-
+/* Mark the cache as valid and empty. */
 static void
 reset_dircache (dircache_t * dircache)
 {
 	ASSERT( dircache != NULL );
 
 	dircache->eof = FALSE;
-	dircache->cache_used = dircache->base = 0;
+	dircache->cache_used = 0;
 	dircache->is_valid = TRUE;
 	dircache->sid = -1;
 	dircache->close_sid = -1;
@@ -113,7 +103,7 @@ get_next_dircache_entry(dircache_t * dircache)
 
 	if(dircache->is_valid && dircache->cache_used < dircache->cache_size)
 	{
-		LOG(("read directory entry '%s', now %ld entries in cache (of %ld)\n",
+		D(("read directory entry '%s', now %ld entries in cache (of %ld)",
 			escape_name(dircache->cache[dircache->cache_used].complete_path),
 			dircache->cache_used+1,
 			dircache->cache_size));
@@ -123,7 +113,7 @@ get_next_dircache_entry(dircache_t * dircache)
 		if(dircache->cache_used < dircache->cache_size)
 			result = &dircache->cache[dircache->cache_used];
 		else
-			LOG(("directory cache is now full\n"));
+			SHOWMSG("directory cache is now full");
 	}
 
 	return(result);
@@ -149,7 +139,7 @@ invalidate_dircache(dircache_t * dircache)
 
 	if(dircache->cache_for != NULL)
 	{
-		LOG(("invalidating directory cache for '%s'\n", escape_name(dircache->cache_for->dirent.complete_path)));
+		D(("invalidating directory cache for '%s'", escape_name(dircache->cache_for->dirent.complete_path)));
 
 		dircache->cache_for->dircache = NULL;
 		dircache->cache_for = NULL;
@@ -320,7 +310,6 @@ smba_connect (
 	const char *				workgroup_name,
 	int							cache_size,
 	int							opt_cache_tables,
-	int							opt_cache_expires,
 	int							max_transmit,
 	int							timeout,
 	int							opt_raw_smb,
@@ -367,32 +356,32 @@ smba_connect (
 	if(opt_raw_smb)
 		res->server.raw_smb = TRUE;
 
-	LOG(("use raw SMB = %s\n",opt_raw_smb ? "yes" : "no"));
+	D(("use raw SMB = %s",opt_raw_smb ? "yes" : "no"));
 
 	/* Timeout for send/receive operations in seconds. */
 	res->server.timeout = timeout;
 
-	LOG(("send/receive/connect timeout = %ld seconds%s\n",timeout,timeout > 0 ? "" : " (= default timeout)"));
+	D(("send/receive/connect timeout = %ld seconds%s",timeout,timeout > 0 ? "" : " (= default timeout)"));
 
 	/* Enable Unicode support if the server supports it, too. */
 	res->server.use_unicode = opt_unicode;
 
-	LOG(("use Unicode = %s\n",opt_unicode ? "yes" : "no"));
+	D(("use Unicode = %s",opt_unicode ? "yes" : "no"));
 
 	/* Prefer SMB core protocol commands to NT1 commands, if possible. */
 	res->server.prefer_core_protocol = opt_prefer_core_protocol;
 
-	LOG(("prefer core protocol = %s\n",opt_prefer_core_protocol ? "yes" : "no"));
+	D(("prefer core protocol = %s",opt_prefer_core_protocol ? "yes" : "no"));
 
 	/* Path names are case-sensitive. */
 	res->server.case_sensitive = opt_case_sensitive;
 
-	LOG(("path names are case sensitive = %s\n",opt_case_sensitive ? "yes" : "no"));
+	D(("path names are case sensitive = %s",opt_case_sensitive ? "yes" : "no"));
 
 	/* Delay the use of Unicode strings during session setup. */
 	res->server.session_setup_delay_unicode = opt_session_setup_delay_unicode;
 
-	LOG(("delay use of unicode during session setup = %s\n",opt_session_setup_delay_unicode ? "yes" : "no"));
+	D(("delay use of unicode during session setup = %s",opt_session_setup_delay_unicode ? "yes" : "no"));
 
 	/* Do not send SMB header and payload for write operations separately,
 	 * but in a single chunk if their combined size is smaller than
@@ -400,7 +389,7 @@ smba_connect (
 	 */
 	res->server.smb_write_threshold = opt_smb_request_write_threshold;
 
-	LOG(("SMB write request threshold size = %ld bytes\n", res->server.smb_write_threshold));
+	D(("SMB write request threshold size = %ld bytes", res->server.smb_write_threshold));
 
 	/* Do not receive SMB header and payload for read operations separately,
 	 * but in a single chunk if their combined size is smaller than
@@ -408,12 +397,12 @@ smba_connect (
 	 */
 	res->server.smb_read_threshold = opt_smb_request_read_threshold;
 
-	LOG(("SMB read request threshold size = %ld bytes\n", res->server.smb_read_threshold));
+	D(("SMB read request threshold size = %ld bytes", res->server.smb_read_threshold));
 
 	/* Use sendmsg() instead of send() where useful? */
 	res->server.scatter_gather = opt_scatter_gather;
 
-	LOG(("use sendmsg() instead of send() where useful = %s\n",opt_scatter_gather ? "yes" : "no"));
+	D(("use sendmsg() instead of send() where useful = %s",opt_scatter_gather ? "yes" : "no"));
 
 	/* Disable the Nagle algorithm, causing send() to immediately
 	 * result in the data being transmitted?
@@ -429,11 +418,9 @@ smba_connect (
 	/* Enable asynchronous SMB_COM_WRITE_RAW operations? */
 	res->server.write_behind = opt_write_behind;
 
-	LOG(("use asynchronous SMB_COM_WRITE_RAW operations = %s\n",opt_write_behind ? "yes" : "no"));
+	D(("use asynchronous SMB_COM_WRITE_RAW operations = %s",opt_write_behind ? "yes" : "no"));
 
-	LOG(("cache size = %ld entries\n", cache_size));
-
-	res->server.cache_expires = opt_cache_expires;
+	D(("cache size = %ld entries", cache_size));
 
 	if(setup_server_dircache (res, cache_size, opt_cache_tables) < 0)
 	{
@@ -445,7 +432,7 @@ smba_connect (
 
 	strlcpy(data.workgroup_name,workgroup_name,sizeof(data.workgroup_name));
 
-	LOG(("workgroup name = '%s'\n",workgroup_name));
+	D(("workgroup name = '%s'",workgroup_name));
 
 	res->server.abstraction = res;
 
@@ -459,9 +446,9 @@ smba_connect (
 	if ((s = strchr (hostname, '.')) != NULL)
 		(*s) = '\0';
 
-	LOG(("local host name = '%s'\n",hostname));
+	D(("local host name = '%s'",hostname));
 
-	LOG(("server ip address = %s\n",Inet_NtoA(server_ip_addr.sin_addr.s_addr)));
+	D(("server ip address = %s",Inet_NtoA(server_ip_addr.sin_addr.s_addr)));
 
 	data.addr = server_ip_addr;
 
@@ -477,7 +464,7 @@ smba_connect (
 		{
 			data.addr.sin_port = servent->s_port;
 
-			LOG(("using port number %ld\n",ntohs(data.addr.sin_port)));
+			D(("using port number %ld",ntohs(data.addr.sin_port)));
 		}
 		else
 		{
@@ -495,7 +482,7 @@ smba_connect (
 				{
 					data.addr.sin_port = htons (n);
 
-					LOG(("using port number %ld\n",n));
+					D(("using port number %ld",n));
 				}
 				else
 				{
@@ -524,7 +511,7 @@ smba_connect (
 		else
 			port = htons (445);
 
-		LOG(("using port number %ld\n",ntohs(port)));
+		D(("using port number %ld",ntohs(port)));
 
 		data.addr.sin_port = port;
 	}
@@ -538,7 +525,7 @@ smba_connect (
 		else
 			port = htons (139);
 
-		LOG(("using port number %ld\n",ntohs(port)));
+		D(("using port number %ld",ntohs(port)));
 
 		data.addr.sin_port = port;
 	}
@@ -554,24 +541,24 @@ smba_connect (
 
 	strlcpy (data.service, connect_parameters->service, sizeof(data.service));
 
-	LOG(("service = '%s'\n",data.service));
+	D(("service = '%s'",data.service));
 
 	string_toupper (data.service);
 
 	strlcpy (data.username, connect_parameters->username, sizeof(data.username));
 	strlcpy (data.password, connect_parameters->password, sizeof(data.password));
 
-	LOG(("user name = '%s'\n",data.username));
+	D(("user name = '%s'",data.username));
 
 	data.given_max_xmit = max_transmit;
 
-	LOG(("max transmit = %ld bytes\n",max_transmit));
+	D(("max transmit = %ld bytes",max_transmit));
 
 	strlcpy (data.server_name, connect_parameters->server_name, sizeof(data.server_name));
 	strlcpy (data.client_name, connect_parameters->client_name, sizeof(data.client_name));
 
-	LOG(("server name = '%s'\n",data.server_name));
-	LOG(("client name = '%s'\n",data.client_name));
+	D(("server name = '%s'",data.server_name));
+	D(("client name = '%s'",data.client_name));
 
 	if (data.server_name[0] == '\0')
 	{
@@ -649,15 +636,24 @@ smba_disconnect (smba_server_t * server)
 /*****************************************************************************/
 
 static int
-file_attributes_are_stale(ULONG now, const smba_file_t * f)
+file_attributes_are_stale(const smba_file_t * f)
 {
-	int result;
+	int stale;
 
 	ASSERT( f != NULL );
 
-	result = (f->attr_time == 0 || (now > f->attr_time && (now - f->attr_time) > ATTR_CACHE_TIME));
+	if(f->attr_time == 0)
+	{
+		stale = TRUE;
+	}
+	else
+	{
+		ULONG now = get_current_time();
 
-	return(result);
+		stale = (now > f->attr_time && (now - f->attr_time) > ATTR_CACHE_TIME);
+	}
+
+	return(stale);
 }
 
 /*****************************************************************************/
@@ -672,26 +668,24 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 
 	if (!f->is_valid || (need_fid && !f->dirent.opened))
 	{
-		ULONG now = get_current_time();
-
 		server = f->server;
 
-		if (!f->is_valid || file_attributes_are_stale(now, f))
+		if (!f->is_valid || file_attributes_are_stale(f))
 		{
 			if (!f->is_valid || f->attr_time == 0)
-				LOG(("file attributes not yet known\n"));
+				D(("file '%s' attributes are not yet known",escape_name(f->dirent.complete_path)));
 			else
-				LOG(("file attributes need to be updated\n"));
+				D(("file '%s' attributes are need to be updated",escape_name(f->dirent.complete_path)));
 
 			if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
 			{
-				LOG(("using the LAN Manager 2.0 getattr() variant\n"));
+				SHOWMSG("using the LAN Manager 2.0 getattr() variant");
 
 				result = smb_query_path_information (&server->server, f->dirent.complete_path, f->dirent.len, 0, &f->dirent, error_ptr);
 			}
 			else
 			{
-				LOG(("using the legacy getattr() variant\n"));
+				SHOWMSG("using the legacy getattr() variant");
 
 				result = smb_proc_getattr_core (&server->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
 			}
@@ -708,9 +702,9 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 				{
 					if(!f->dirent.opened)
 					{
-						LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
+						D(("opening file '%s'", escape_name(f->dirent.complete_path)));
 
-						LOG(("using the LAN Manager 2.0 open() variant\n"));
+						SHOWMSG("using the LAN Manager 2.0 open() variant");
 
 						result = smb_proc_open (&server->server, f->dirent.complete_path, f->dirent.len, writable, truncate_file, &f->dirent, error_ptr);
 						if (result < 0)
@@ -718,7 +712,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 					}
 					else
 					{
-						LOG (("file '%s' is already open (fileid=0x%04lx)\n", escape_name(f->dirent.complete_path), f->dirent.fileid));
+						D(("file '%s' is already open (fileid=0x%04lx)", escape_name(f->dirent.complete_path), f->dirent.fileid));
 					}
 				}
 			}
@@ -726,9 +720,9 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 			{
 				if(!f->dirent.opened)
 				{
-					LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
+					D(("opening file '%s'", escape_name(f->dirent.complete_path)));
 
-					LOG(("using the legacy open() variant\n"));
+					SHOWMSG("using the legacy open() variant");
 
 					result = smb_proc_open (&server->server, f->dirent.complete_path, f->dirent.len, writable, truncate_file, &f->dirent, error_ptr);
 					if (result < 0)
@@ -736,7 +730,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 				}
 				else
 				{
-					LOG (("file '%s' is already open (fileid=0x%04lx)\n", escape_name(f->dirent.complete_path), f->dirent.fileid));
+					D(("file '%s' is already open (fileid=0x%04lx)", escape_name(f->dirent.complete_path), f->dirent.fileid));
 				}
 
 				if (server->supports_E || !server->supports_E_known)
@@ -761,7 +755,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
 		{
 			if (f->dircache != NULL)
 			{
-				LOG(("discarding the '%s' directory cache\n", escape_name(f->dirent.complete_path)));
+				D(("discarding the '%s' directory cache", escape_name(f->dirent.complete_path)));
 
 				Remove((struct Node *)f->dircache);
 				AddTail((struct List *)&server->dircache_list, (struct Node *)f->dircache);
@@ -848,7 +842,7 @@ smba_open (
 	f->dirent.len = strlen (name);
 	f->server = s;
 
-	LOG(("open '%s' (writable=%s, truncate_file=%s)\n",
+	D(("open '%s' (writable=%s, truncate_file=%s)",
 		escape_name(name),
 		writable ? "yes" : "no",
 		truncate_file ? "yes" : "no"));
@@ -856,14 +850,14 @@ smba_open (
 	result = make_open (f, open_dont_need_fid, writable, truncate_file, error_ptr);
 	if (result < 0)
 	{
-		LOG(("open failed\n"));
+		SHOWMSG("open failed");
 		goto out;
 	}
 
 	add_smba_file(s, f);
 	s->num_open_files++;
 
-	LOG(("file has been 'opened', number of open files = %ld\n",s->num_open_files));
+	D(("file has been 'opened', number of open files = %ld",s->num_open_files));
 
 	(*file) = f;
 	f = NULL;
@@ -883,9 +877,9 @@ write_attr (smba_file_t * f, int * error_ptr)
 {
 	int result;
 
-	LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
+	D(("file '%s'", escape_name(f->dirent.complete_path)));
 
-	LOG(("mtime = %lu\n",f->dirent.mtime));
+	D(("mtime = %lu",f->dirent.mtime));
 
 	if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
 	{
@@ -894,17 +888,17 @@ write_attr (smba_file_t * f, int * error_ptr)
 		time_t ctime = f->dirent.ctime;
 		dword attr = f->dirent.attr;
 
-		LOG(("mtime = %lu\n",f->dirent.mtime));
-		LOG(("ctime = %lu\n",f->dirent.ctime));
+		D(("mtime = %lu",f->dirent.mtime));
+		D(("ctime = %lu",f->dirent.ctime));
 
-		LOG(("using the LAN Manager 2.0 open() variant\n"));
+		SHOWMSG("using the LAN Manager 2.0 open() variant");
 
 		result = make_open (f, open_need_fid, open_writable, open_dont_truncate, error_ptr);
 		if (result < 0)
 			goto out;
 
-		LOG(("mtime = %lu\n",f->dirent.mtime));
-		LOG(("ctime = %lu\n",f->dirent.ctime));
+		D(("mtime = %lu",f->dirent.mtime));
+		D(("ctime = %lu",f->dirent.ctime));
 
 		f->dirent.mtime = mtime;
 		f->dirent.ctime = ctime;
@@ -923,17 +917,17 @@ write_attr (smba_file_t * f, int * error_ptr)
 		time_t ctime = f->dirent.ctime;
 		dword attr = f->dirent.attr;
 
-		LOG(("mtime = %lu\n",f->dirent.mtime));
-		LOG(("ctime = %lu\n",f->dirent.ctime));
+		D(("mtime = %lu",f->dirent.mtime));
+		D(("ctime = %lu",f->dirent.ctime));
 
-		LOG(("using the legacy open() variant\n"));
+		SHOWMSG("using the legacy open() variant");
 
 		result = make_open (f, open_dont_need_fid, open_writable, open_dont_truncate, error_ptr);
 		if (result < 0)
 			goto out;
 
-		LOG(("mtime = %lu\n",f->dirent.mtime));
-		LOG(("ctime = %lu\n",f->dirent.ctime));
+		D(("mtime = %lu",f->dirent.mtime));
+		D(("ctime = %lu",f->dirent.ctime));
 
 		f->dirent.mtime = mtime;
 		f->dirent.ctime = ctime;
@@ -1029,7 +1023,7 @@ smba_close (smba_server_t * s, smba_file_t * f)
 
 		if (f->dirent.opened)
 		{
-			LOG (("closing file '%s' (fileid=0x%04lx)\n", escape_name(f->dirent.complete_path), f->dirent.fileid));
+			D(("closing file '%s' (fileid=0x%04lx)", escape_name(f->dirent.complete_path), f->dirent.fileid));
 
 			/* Don't change the modification time. */
 			smb_proc_close (&f->server->server, f->dirent.fileid, -1, &ignored_error);
@@ -1046,13 +1040,13 @@ smba_close (smba_server_t * s, smba_file_t * f)
 
 		f->server->num_open_files--;
 
-		LOG(("file closed, number of open files = %ld\n",f->server->num_open_files));
+		D(("file closed, number of open files = %ld",f->server->num_open_files));
 
 		free (f);
 	}
 	else
 	{
-		LOG(("file seems to be invalid\n"));
+		SHOWMSG("file seems to be invalid");
 	}
 
 	LEAVE();
@@ -1071,7 +1065,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 	if (result < 0)
 		goto out;
 
-	LOG(("read %ld bytes from offset %s\n",len,convert_quad_to_string(offset)));
+	D(("read %ld bytes from offset %s",len,convert_quad_to_string(offset)));
 
 	/* SMB_COM_READ_ANDX supported? */
 	if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_core_protocol)
@@ -1113,7 +1107,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 		if(max_readx_size > f->server->server.transmit_buffer_size - 62)
 			max_readx_size = f->server->server.transmit_buffer_size - 62;
 
-		LOG (("len = %ld, max_readx_size = %ld\n", len, max_readx_size));
+		D(("len = %ld, max_readx_size = %ld", len, max_readx_size));
 
 		do
 		{
@@ -1130,7 +1124,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 
 			if(result < count)
 			{
-				LOG(("read returned fewer characters than expected (%ld < %ld)\n",result,count));
+				D(("read returned fewer characters than expected (%ld < %ld)",result,count));
 				break;
 			}
 		}
@@ -1161,7 +1155,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 			result = smb_proc_read_raw (&f->server->server, &f->dirent, &position_quad, n, data, error_ptr);
 			if(result <= 0)
 			{
-				LOG(("!!! wanted to read %ld bytes, got %ld\n",n,result));
+				D(("!!! wanted to read %ld bytes, got %ld",n,result));
 				break;
 			}
 
@@ -1172,7 +1166,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 
 			if(result < n)
 			{
-				LOG(("read returned fewer characters than expected (%ld < %ld)\n",result,n));
+				D(("read returned fewer characters than expected (%ld < %ld)",result,n));
 				break;
 			}
 		}
@@ -1240,7 +1234,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
 
 			if(result < count)
 			{
-				LOG(("read returned fewer characters than expected (%ld < %ld)\n",result,count));
+				D(("read returned fewer characters than expected (%ld < %ld)",result,count));
 				break;
 			}
 		}
@@ -1267,7 +1261,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 	if (result < 0)
 		goto out;
 
-	D(("maximum buffer size = %ld\n", f->server->server.max_buffer_size));
+	D(("maximum buffer size = %ld", f->server->server.max_buffer_size));
 
 	max_buffer_size = f->server->server.max_buffer_size;
 
@@ -1310,7 +1304,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 		if((f->server->server.capabilities & CAP_LARGE_WRITEX) != 0)
 			max_writex_size = 65535;
 
-		LOG (("len = %ld, max_writex_size = %ld\n", len, max_writex_size));
+		D(("len = %ld, max_writex_size = %ld", len, max_writex_size));
 
 		do
 		{
@@ -1318,13 +1312,13 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 
 			ASSERT( n > 0 );
 
-			LOG(("writing %ld bytes; offset=%s, len=%ld\n", n, convert_quad_to_string(&position_quad), len));
+			D(("writing %ld bytes; offset=%s, len=%ld", n, convert_quad_to_string(&position_quad), len));
 
 			result = smb_proc_writex(&f->server->server, &f->dirent, &position_quad, n, data, error_ptr);
 			if(result < 0)
 				goto out;
 
-			LOG(("number of bytes written = %ld\n", result));
+			D(("number of bytes written = %ld", result));
 
 			data += result;
 			add_64_plus_32_to_64(&position_quad,result,&position_quad);
@@ -1364,7 +1358,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 		if(max_size_smb_com_write_raw > 65535)
 			max_size_smb_com_write_raw = 65535;
 
-		LOG (("len = %ld, max_size_smb_com_write_raw = %ld\n", len, max_size_smb_com_write_raw));
+		D(("len = %ld, max_size_smb_com_write_raw = %ld", len, max_size_smb_com_write_raw));
 
 		do
 		{
@@ -1421,7 +1415,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 		if(max_size_smb_com_write > 65535)
 			max_size_smb_com_write = 65535;
 
-		LOG (("len = %ld, max_size_smb_com_write = %ld\n", len, max_size_smb_com_write));
+		D(("len = %ld, max_size_smb_com_write = %ld", len, max_size_smb_com_write));
 
 		do
 		{
@@ -1443,7 +1437,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
 		while (len > 0);
 	}
 
-	LOG(("num_bytes_written=%ld\n", num_bytes_written));
+	D(("num_bytes_written=%ld", num_bytes_written));
 
 	result = num_bytes_written;
 
@@ -1546,24 +1540,21 @@ int
 smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
 {
 	int result;
-	ULONG now;
 
 	result = make_open (f, open_dont_need_fid, open_read_only, open_dont_truncate, error_ptr);
 	if (result < 0)
 		goto out;
 
-	now = get_current_time();
-
-	if (file_attributes_are_stale (now, f))
+	if (file_attributes_are_stale (f))
 	{
-		LOG (("file '%s' attributes %s\n",
+		D(("file '%s' attributes %s",
 			escape_name(f->dirent.complete_path),
 			(f->attr_time == 0) ? "are not yet known" : "need to be updated"
 		));
 
 		if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
 		{
-			LOG(("using the LAN Manager 2.0 path query variant\n"));
+			SHOWMSG("using the LAN Manager 2.0 path query variant");
 
 			if (f->dirent.opened)
 				result = smb_query_path_information (&f->server->server, NULL, 0, f->dirent.fileid, &f->dirent, error_ptr);
@@ -1572,17 +1563,17 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
 		}
 		else
 		{
-			LOG(("using the legacy path query variant\n"));
+			SHOWMSG("using the legacy path query variant");
 
 			if (f->dirent.opened && f->server->supports_E)
 			{
-				LOG(("using smb_proc_getattrE\n"));
+				SHOWMSG("using smb_proc_getattrE");
 
 				result = smb_proc_getattrE (&f->server->server, &f->dirent, error_ptr);
 			}
 			else
 			{
-				LOG(("using smb_proc_getattr_core\n"));
+				SHOWMSG("using smb_proc_getattr_core");
 
 				result = smb_proc_getattr_core (&f->server->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
 			}
@@ -1591,7 +1582,7 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
 		if (result < 0)
 			goto out;
 
-		f->attr_time = now;
+		f->attr_time = get_current_time();
 	}
 
 	copy_dirent_to_stat_data(data, &f->dirent);
@@ -1614,7 +1605,7 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 	{
 		if (st->atime != 0 && st->atime != (time_t)-1 && f->dirent.atime != st->atime)
 		{
-			LOG(("atime changed to %lu\n",st->atime));
+			D(("atime changed to %lu",st->atime));
 
 			f->dirent.atime = st->atime;
 			times_changed = TRUE;
@@ -1622,7 +1613,7 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 
 		if (st->ctime != 0 && st->ctime != (time_t)-1 && f->dirent.ctime != st->ctime)
 		{
-			LOG(("ctime changed to %lu\n",st->ctime));
+			D(("ctime changed to %lu",st->ctime));
 
 			f->dirent.ctime = st->ctime;
 			times_changed = TRUE;
@@ -1630,7 +1621,7 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 
 		if (st->mtime != 0 && st->mtime != (time_t)-1 && f->dirent.mtime != st->mtime)
 		{
-			LOG(("mtime changed to %lu\n",st->mtime));
+			D(("mtime changed to %lu",st->mtime));
 
 			f->dirent.mtime = st->mtime;
 			times_changed = TRUE;
@@ -1659,6 +1650,8 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 			result = write_attr (f, error_ptr);
 			if (result < 0)
 				goto out;
+
+			f->attr_time = get_current_time();	
 		}
 	}
 
@@ -1670,13 +1663,13 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 
 		if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
 		{
-			LOG(("using the LAN Manager 2.0 trunc variant\n"));
+			SHOWMSG("using the LAN Manager 2.0 trunc variant");
 
 			result = smb_set_file_information (&f->server->server, &f->dirent, size, error_ptr);
 		}
 		else
 		{
-			LOG(("using the legacy trunc variant (which cannot truncate files)\n"));
+			SHOWMSG("using the legacy trunc variant (which cannot truncate files)");
 
 			result = smb_proc_trunc (&f->server->server, &f->dirent, size->Low, error_ptr);
 		}
@@ -1696,14 +1689,14 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
 /*****************************************************************************/
 
 int
-smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t callback, int * eof_ptr, int * error_ptr)
+smba_readdir (smba_file_t * f, int offs, int restart, void *callback_data, smba_callback_t callback, int * eof_ptr, int * error_ptr)
 {
 	const struct smb_dirent * dirent;
-	int cache_index, o, eof, count = 0;
+	int cache_index = 0;
+	int eof = FALSE;
 	int num_entries;
 	smba_stat_t data;
 	int result;
-	ULONG now;
 
 	if(eof_ptr != NULL)
 		(*eof_ptr) = FALSE;
@@ -1712,8 +1705,6 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 	if (result < 0)
 		goto out;
 
-	now = get_current_time();
-
 	/* get a cache for this directory unless we already have one */
 	if (f->dircache == NULL)
 	{
@@ -1727,7 +1718,7 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 		/* Is the cache currently in use? */
 		if (dircache->cache_for != NULL)
 		{
-			LOG(("stealing cache from '%s'\n", escape_name(dircache->cache_for->dirent.complete_path)));
+			D(("stealing cache from '%s'", escape_name(dircache->cache_for->dirent.complete_path)));
 
 			/* Steal the cache from the other directory? */
 			dircache->cache_for->dircache = NULL;
@@ -1738,21 +1729,21 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 		dircache->cache_for = f;
 		f->dircache = dircache;
 	}
+	else if (restart)
+	{
+		int sid;
+
+		D(("refilling cache for '%s'", escape_name(f->dircache->cache_for->dirent.complete_path)));
+
+		sid = f->dircache->sid;
+
+		reset_dircache(f->dircache);
+
+		f->dircache->close_sid = sid;
+	}
 	else
 	{
-		/* Has the cache already become stale? */
-		if (dircache_is_stale(now, f->server->server.cache_expires, f->dircache))
-		{
-			int sid;
-
-			LOG (("cache for '%s' has become stale\n", escape_name(f->dircache->cache_for->dirent.complete_path)));
-
-			sid = f->dircache->sid;
-
-			reset_dircache(f->dircache);
-
-			f->dircache->close_sid = sid;
-		}
+		cache_index = offs;
 	}
 
 	/* Make sure that the cache is not easily stolen. */
@@ -1762,49 +1753,42 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 		AddHead((struct List *)&f->server->dircache_list, (struct Node *)f->dircache);
 	}
 
-	/* Read each single directory entry, drawing upon the
-	 * cache contents, if possible.
-	 */
-	for (cache_index = offs ; ; cache_index++)
+	while(TRUE)
 	{
-		/* Nothing more to be read? */
-		if (cache_index >= f->dircache->base + f->dircache->cache_used && f->dircache->eof)
-			break;
-
-		/* Is this entry not in the cache? */
-		if (cache_index < f->dircache->base || cache_index >= f->dircache->base + f->dircache->cache_used)
+		if(cache_index >= f->dircache->cache_used)
 		{
-			LOG (("cachefill for '%s'\n", escape_name(f->dirent.complete_path)));
-			LOG (("\tbase was: %ld, len was: %ld, newbase=%ld\n", f->dircache->base, f->dircache->cache_used, cache_index));
+			if(f->dircache->eof)
+			{
+				SHOWMSG("no further directory entries are available");
 
-			/* Start over and read the next entries, beginning with
-			 * entry at offset 'cache_index'.
-			 */
-			f->dircache->cache_used = 0;
-			f->dircache->base = cache_index;
+				eof = TRUE;
+				break;
+			}
+
+			SHOWMSG("filling the directory cache");
+
+			/* Start over and read the next entries. */
+			f->dircache->cache_used = cache_index = 0;
 
 			/* Try to read up as many entries as will fit into
 			 * the cache (cache_size).
 			 */
-			num_entries = smb_proc_readdir (&f->server->server, f->dirent.complete_path, cache_index, f->dircache, &eof, error_ptr);
-
-			/* We stop on error, or if the directory is empty. */
-			if (num_entries <= 0)
+			num_entries = smb_proc_readdir (&f->server->server, f->dirent.complete_path, f->dircache, &eof, error_ptr);
+			if (num_entries < 0)
 			{
-				if (num_entries == 0)
-					LOG(("no directory entries read\n"));
-
 				result = num_entries;
 				goto out;
 			}
 
+			D(("cachefill returned %ld entries", num_entries));
+
 			/* The cache may have been invalidated because an error
 			 * occured (e.g. server connection was terminated), or if
 			 * the cache size was changed.
 			 */
 			if (f->dircache == NULL || !f->dircache->is_valid)
 			{
-				LOG (("dircache was invalidated, bailing out!\n"));
+				SHOWMSG("dircache was invalidated, bailing out!");
 
 				(*error_ptr) = ENOENT;
 
@@ -1812,25 +1796,21 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 				goto out;
 			}
 
-			/* f->dircache->cache_used = num_entries; */
 			f->dircache->eof = eof;
-			f->dircache->created_at = now;
 
-			LOG (("cachefill with %ld entries\n", num_entries));
+			if(eof)
+				SHOWMSG("no further directory entries are available");
+
+			if(num_entries == 0)
+				break;
 		}
 
-		o = cache_index - f->dircache->base;
+		/* Will this be the last directory entry to be processed? */
+		eof = (f->dircache->eof && cache_index+1 == f->dircache->cache_used);
 
-		/* Is this the last directory entry to be delivered? */
-		eof = (o >= (f->dircache->cache_used - 1) && f->dircache->eof);
-		if(eof && eof_ptr != NULL)
-			(*eof_ptr) = TRUE;
+		dirent = &f->dircache->cache[cache_index];
 
-		count++;
-
-		dirent = &f->dircache->cache[o];
-
-		LOG (("delivering '%s', cache_index=%ld, last entry=%s\n",
+		D(("delivering '%s', cache index=%ld, last entry=%s",
 			escape_name(dirent->complete_path),
 			cache_index,
 			eof ? "yes" : "no")
@@ -1838,14 +1818,19 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
 
 		copy_dirent_to_stat_data(&data, dirent);
 
-		if ((*callback) (callback_data, cache_index, cache_index + 1, dirent->complete_path, eof, &data))
+		if ((*callback) (callback_data, cache_index, cache_index+1, dirent->complete_path, eof, &data))
 			break;
-	}
 
-	result = count;
+		cache_index++;
+	}
+	
+	result = 0;
 
  out:
 
+	if(eof && eof_ptr != NULL)
+		(*eof_ptr) = TRUE;
+
 	return result;
 }
 
@@ -1864,7 +1849,7 @@ allocate_path_name(const smba_file_t * dir, const char *name, size_t * path_name
 	if(path != NULL)
 	{
 		memcpy (path, dir->dirent.complete_path, dir_len);
-		path[dir_len++] = DOS_PATHSEP;
+		path[dir_len++] = '\\';
 		memcpy(&path[dir_len], name, len+1); /* length includes terminating NUL character */
 
 		ASSERT( path_name_len_ptr != NULL );
@@ -1905,7 +1890,7 @@ smba_create (smba_file_t * dir, const char *name, int truncate, int * error_ptr)
 
 	if (!dir->server->server.prefer_core_protocol && dir->server->server.protocol >= PROTOCOL_LANMAN2)
 	{
-		LOG(("using the LAN Manager 2.0 creat variant\n"));
+		SHOWMSG("using the LAN Manager 2.0 creat variant");
 
 		result = smb_proc_open (&dir->server->server, path, path_len, open_writable, truncate, &entry, error_ptr);
 		if(result < 0)
@@ -1913,7 +1898,7 @@ smba_create (smba_file_t * dir, const char *name, int truncate, int * error_ptr)
 	}
 	else
 	{
-		LOG(("using the legacy creat variant\n"));
+		SHOWMSG("using the legacy creat variant");
 
 		result = smb_proc_create (&dir->server->server, path, path_len, &entry, error_ptr);
 		if(result < 0)
@@ -1981,7 +1966,7 @@ invalidate_smba_file(smba_server_t * s, smba_file_t *f, const char *path, int *
 		result = smb_proc_close (&s->server, f->dirent.fileid, -1, error_ptr);
 		if(result < 0)
 		{
-			LOG(("closing '%s' with file id %ld failed\n", escape_name(path), f->dirent.fileid));
+			D(("closing '%s' with file id %ld failed", escape_name(path), f->dirent.fileid));
 			goto out;
 		}
 
@@ -2375,7 +2360,6 @@ smba_start(
 	const char *		opt_servername,
 	int					opt_cachesize,
 	int					opt_cache_tables,
-	int					opt_cache_expires,
 	int					opt_max_transmit,
 	int					opt_timeout,
 	int					opt_raw_smb,
@@ -2441,7 +2425,7 @@ smba_start(
 		char * dot;
 		int lookup_error;
 
-		LOG(("server name is '%s'\n", server));
+		D(("server name is '%s'", server));
 
 		h_errno = 0;
 
@@ -2464,7 +2448,7 @@ smba_start(
 			goto out;
 		}
 
-		LOG(("server network address found (%s)\n", Inet_NtoA(server_ip_address.sin_addr.s_addr)));
+		D(("server network address found (%s)", Inet_NtoA(server_ip_address.sin_addr.s_addr)));
 
 		/* No workgroup given? Ask the server... */
 		if(opt_workgroup == NULL)
@@ -2493,7 +2477,7 @@ smba_start(
 		char workgroup_name[16];
 		const char * name;
 
-		LOG(("server network address is %s\n", server));
+		D(("server network address is %s", server));
 
 		/* Ask the server about its name and its workgroup. We need to
 		 * know the name to continue, and the workgroup name may
@@ -2501,7 +2485,7 @@ smba_start(
 		 */
 		if(SendNetBIOSStatusQuery(server_ip_address,server_name,sizeof(server_name),workgroup_name,sizeof(workgroup_name)) == 0 && server_name[0] != '\0')
 		{
-			LOG(("server %s provided its own name '%s', with workgroup '%s'\n",Inet_NtoA(server_ip_address.sin_addr.s_addr),server_name,workgroup_name));
+			D(("server %s provided its own name '%s', with workgroup '%s'",Inet_NtoA(server_ip_address.sin_addr.s_addr),server_name,workgroup_name));
 
 			/* No workgroup given? Use what the server told us... */
 			if(opt_workgroup == NULL && workgroup_name[0] != '\0')
@@ -2534,7 +2518,7 @@ smba_start(
 
 			name = h->h_name;
 
-			LOG(("server host name found (%s)\n",name));
+			D(("server host name found (%s)",name));
 
 			/* Brian Willette: Now we will set the server name to the DNS
 			 * hostname, hopefully this will be the same as the NetBIOS name for
@@ -2625,7 +2609,7 @@ smba_start(
 	par.username = username;
 	par.password = password;
 
-	LOG(("server name = '%s', client name = '%s', workgroup name = '%s', user name = '%s'\n",
+	D(("server name = '%s', client name = '%s', workgroup name = '%s', user name = '%s'",
 		server_name, client_name, workgroup, username));
 
 	if(smba_connect (
@@ -2636,7 +2620,6 @@ smba_start(
 		workgroup,
 		opt_cachesize,
 		opt_cache_tables,
-		opt_cache_expires,
 		opt_max_transmit,
 		opt_timeout,
 		opt_raw_smb,
diff --git a/source_code/smb_abstraction.h b/source_code/smb_abstraction.h
index 33f2d38..2105911 100644
--- a/source_code/smb_abstraction.h
+++ b/source_code/smb_abstraction.h
@@ -177,7 +177,7 @@ int smba_write(smba_file_t *f, const char *data, long len, const QUAD *const off
 int smba_lockrec(smba_file_t *f, long offset, long len, long mode, int unlocked, long timeout, int *error_ptr);
 int smba_getattr(smba_file_t *f, smba_stat_t *data, int *error_ptr);
 int smba_setattr(smba_file_t *f, const smba_stat_t *data, const QUAD *const size, int *error_ptr);
-int smba_readdir(smba_file_t *f, int offs, void *callback_data, smba_callback_t callback, int *eof_ptr, int *error_ptr);
+int smba_readdir(smba_file_t *f, int offs, int restart, void *callback_data, smba_callback_t callback, int *eof_ptr, int *error_ptr);
 int smba_create(smba_file_t *dir, const char *name, int truncate, int *error_ptr);
 int smba_mkdir(smba_file_t *dir, const char *name, int *error_ptr);
 int smba_remove(smba_server_t *s, const char *path, int *error_ptr);
@@ -185,7 +185,7 @@ int smba_rmdir(smba_server_t *s, const char *path, int *error_ptr);
 int smba_rename(smba_server_t *s, const char *from, const char *to, int *error_ptr);
 int smba_statfs(smba_server_t *s, long *bsize, long *blocks, long *bfree, int *error_ptr);
 void smba_invalidate_all_inodes(smba_server_t *server);
-int smba_start(const char *service, const char *opt_workgroup, const char *opt_username, const char *opt_password, const char *opt_clientname, const char *opt_servername, int opt_cachesize, int opt_cache_tables, int opt_cache_expires, int opt_max_transmit, int opt_timeout, int opt_raw_smb, int opt_unicode, int opt_prefer_core_protocol, int opt_case_sensitive, int opt_session_setup_delay_unicode, int opt_write_behind, int opt_smb_request_write_threshold, int opt_smb_request_read_threshold, int opt_scatter_gather, int opt_tcp_no_delay, int opt_socket_receive_buffer_size, int opt_socket_send_buffer_size, int *error_ptr, int *smb_error_class_ptr, int *smb_error_ptr, smba_connect_parameters_t *smba_connect_par, smba_server_t **smba_server_ptr);
+int smba_start(const char *service, const char *opt_workgroup, const char *opt_username, const char *opt_password, const char *opt_clientname, const char *opt_servername, int opt_cachesize, int opt_cache_tables, int opt_max_transmit, int opt_timeout, int opt_raw_smb, int opt_unicode, int opt_prefer_core_protocol, int opt_case_sensitive, int opt_session_setup_delay_unicode, int opt_write_behind, int opt_smb_request_write_threshold, int opt_smb_request_read_threshold, int opt_scatter_gather, int opt_tcp_no_delay, int opt_socket_receive_buffer_size, int opt_socket_send_buffer_size, int *error_ptr, int *smb_error_class_ptr, int *smb_error_ptr, smba_connect_parameters_t *smba_connect_par, smba_server_t **smba_server_ptr);
 int smba_get_dircache_size(struct smba_server *server);
 int smba_change_dircache_size(struct smba_server *server, int cache_size);
 
diff --git a/source_code/smbfs_rev.h b/source_code/smbfs_rev.h
index 208b4c6..25050c5 100644
--- a/source_code/smbfs_rev.h
+++ b/source_code/smbfs_rev.h
@@ -1,6 +1,6 @@
 #define VERSION		2
-#define REVISION	19
-#define DATE		"23.2.2019"
-#define VERS		"smbfs 2.19"
-#define VSTRING		"smbfs 2.19 (23.2.2019)\r\n"
-#define VERSTAG		"\0$VER: smbfs 2.19 (23.2.2019)"
+#define REVISION	20
+#define DATE		"27.2.2019"
+#define VERS		"smbfs 2.20"
+#define VSTRING		"smbfs 2.20 (27.2.2019)\r\n"
+#define VERSTAG		"\0$VER: smbfs 2.20 (27.2.2019)"
diff --git a/source_code/smbfs_rev.rev b/source_code/smbfs_rev.rev
index d6b2404..209e3ef 100644
--- a/source_code/smbfs_rev.rev
+++ b/source_code/smbfs_rev.rev
@@ -1 +1 @@
-19
+20
diff --git a/source_code/sock.c b/source_code/sock.c
index 621769c..1cb770b 100644
--- a/source_code/sock.c
+++ b/source_code/sock.c
@@ -195,13 +195,13 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p
 	{
 		(*error_ptr) = errno;
 
-		LOG (("recv error = %ld\n", (*error_ptr)));
+		D(("recv error = %ld", (*error_ptr)));
 		goto out;
 	}
 
 	if (result < NETBIOS_HEADER_SIZE)
 	{
-		LOG (("expected %ld bytes, got %ld\n", NETBIOS_HEADER_SIZE, result));
+		D(("expected %ld bytes, got %ld", NETBIOS_HEADER_SIZE, result));
 
 		(*error_ptr) = error_end_of_file;
 
@@ -234,7 +234,7 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p
 			 * NetBIOS session response, but for any command
 			 * these message types are invalid.
 			 */
-			LOG(("Invalid session header type 0x%02lx\n", netbios_session_buf[0]));
+			D(("Invalid session header type 0x%02lx", netbios_session_buf[0]));
 
 			(*error_ptr) = error_invalid_netbios_session;
 
@@ -250,7 +250,7 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p
 		/* The length in the NetBIOS header is the raw data length (17 bits) */
 		if (netbios_session_payload_size > server->transmit_buffer_allocation_size)
 		{
-			LOG(("Received length (%ld) > max_xmit (%ld)!\n", netbios_session_payload_size, server->transmit_buffer_allocation_size));
+			D(("Received length (%ld) > max_xmit (%ld)!", netbios_session_payload_size, server->transmit_buffer_allocation_size));
 
 			(*error_ptr) = error_message_exceeds_buffer_size;
 
@@ -263,7 +263,7 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p
 		{
 			(*error_ptr) = errno;
 
-			LOG(("recv error = %ld\n", (*error_ptr)));
+			D(("recv error = %ld", (*error_ptr)));
 			goto out;
 		}
 	}
@@ -320,7 +320,7 @@ smb_receive_raw (
 		{
 			(*error_ptr) = errno;
 
-			LOG (("recv error = %ld\n", (*error_ptr)));
+			D(("recv error = %ld", (*error_ptr)));
 
 			PROFILE_POP("SMB receive raw header");
 
@@ -329,7 +329,7 @@ smb_receive_raw (
 
 		if (result < NETBIOS_HEADER_SIZE)
 		{
-			LOG (("expected %ld bytes, got %ld for the NetBIOS header\n", NETBIOS_HEADER_SIZE, result));
+			D(("expected %ld bytes, got %ld for the NetBIOS header", NETBIOS_HEADER_SIZE, result));
 
 			(*error_ptr) = error_end_of_file;
 
@@ -364,7 +364,7 @@ smb_receive_raw (
 				{
 					(*error_ptr) = errno;
 
-					LOG (("recv error = %ld\n", (*error_ptr)));
+					D(("recv error = %ld", (*error_ptr)));
 
 					PROFILE_POP("SMB receive raw header");
 
@@ -373,7 +373,7 @@ smb_receive_raw (
 
 				if(result < netbios_session_payload_size)
 				{
-					LOG (("result (%ld) < %ld\n", result, netbios_session_payload_size));
+					D(("result (%ld) < %ld", result, netbios_session_payload_size));
 
 					(*error_ptr) = error_end_of_file;
 
@@ -398,7 +398,7 @@ smb_receive_raw (
 		 */
 		if (netbios_session_buf[0] == 0x85)
 		{
-			LOG (("Got SESSION KEEP ALIVE\n"));
+			SHOWMSG("Got SESSION KEEP ALIVE");
 			continue;
 		}
 		/* Is this a regular session message? This is what
@@ -432,7 +432,7 @@ smb_receive_raw (
 				 */
 				if(command != 0)
 				{
-					LOG (("Invalid session header type 0x%02lx\n", netbios_session_buf[0]));
+					D(("Invalid session header type 0x%02lx", netbios_session_buf[0]));
 
 					(*error_ptr) = error_invalid_netbios_session;
 
@@ -456,7 +456,7 @@ smb_receive_raw (
 	len = netbios_session_payload_size;
 	if (len > max_raw_length)
 	{
-		LOG (("Received length (%ld) > max_xmit (%ld)!\n", len, max_raw_length));
+		D(("Received length (%ld) > max_xmit (%ld)!", len, max_raw_length));
 
 		(*error_ptr) = error_message_exceeds_buffer_size;
 
@@ -493,9 +493,9 @@ smb_receive_raw (
 		{
 			int num_bytes_received = 0;
 
-			LOG(("receiving SMB message and payload separately\n"));
+			SHOWMSG("receiving SMB message and payload separately");
 
-			LOG(("input_payload=0x%08lx, payload_size=%ld\n", (unsigned long)input_payload, input_payload_size));
+			D(("input_payload=0x%08lx, payload_size=%ld", (unsigned long)input_payload, input_payload_size));
 
 			if(command == SMBreadX)
 			{
@@ -522,7 +522,7 @@ smb_receive_raw (
 				 * This adds up to 59 bytes.
 				 */
 
-				LOG(("SMBreadX: reading the first %ld bytes\n", 59));
+				D(("SMBreadX: reading the first %ld bytes", 59));
 
 				ASSERT( target != NULL );
 
@@ -531,7 +531,7 @@ smb_receive_raw (
 				{
 					(*error_ptr) = errno;
 
-					LOG (("recv error = %ld\n", (*error_ptr)));
+					D(("recv error = %ld", (*error_ptr)));
 
 					PROFILE_POP("SMBreadX");
 
@@ -546,7 +546,7 @@ smb_receive_raw (
 				if(num_bytes_received < 59)
 				{
 					/* End of file */
-					LOG (("EOF\n"));
+					SHOWMSG("EOF");
 
 					(*error_ptr) = error_end_of_file;
 
@@ -564,14 +564,14 @@ smb_receive_raw (
 				/* Skip the padding bytes, if any. */
 				if(data_offset > 59)
 				{
-					LOG (("skipping %ld padding bytes\n", data_offset - 59));
+					D(("skipping %ld padding bytes", data_offset - 59));
 
 					result = receive_all (sock_fd, target + 59, data_offset - 59);
 					if (result < 0)
 					{
 						(*error_ptr) = errno;
 
-						LOG (("recv error = %ld\n", (*error_ptr)));
+						D(("recv error = %ld", (*error_ptr)));
 
 						PROFILE_POP("SMBreadX");
 
@@ -582,7 +582,7 @@ smb_receive_raw (
 					if(result < data_offset - 59)
 					{
 						/* End of file */
-						LOG (("EOF\n"));
+						SHOWMSG("EOF");
 
 						(*error_ptr) = error_end_of_file;
 
@@ -607,7 +607,7 @@ smb_receive_raw (
 				{
 					(*error_ptr) = errno;
 
-					LOG (("recv error = %ld\n", (*error_ptr)));
+					D(("recv error = %ld", (*error_ptr)));
 
 					PROFILE_POP("SMBreadX");
 
@@ -617,7 +617,7 @@ smb_receive_raw (
 				if(result < data_length)
 				{
 					/* End of file */
-					LOG (("EOF\n"));
+					SHOWMSG("EOF");
 
 					(*error_ptr) = error_end_of_file;
 
@@ -635,14 +635,14 @@ smb_receive_raw (
 				 */
 				if(num_bytes_received < len)
 				{
-					LOG(("reading the remaining %ld bytes; this should never happen\n", len - num_bytes_received ));
+					D(("reading the remaining %ld bytes; this should never happen", len - num_bytes_received ));
 
 					result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received);
 					if (result < 0)
 					{
 						(*error_ptr) = errno;
 
-						LOG (("recv error = %ld\n", (*error_ptr)));
+						D(("recv error = %ld", (*error_ptr)));
 
 						PROFILE_POP("SMBreadX");
 
@@ -652,7 +652,7 @@ smb_receive_raw (
 					if(result < len - num_bytes_received)
 					{
 						/* End of file */
-						LOG (("EOF\n"));
+						SHOWMSG("EOF");
 
 						(*error_ptr) = error_end_of_file;
 
@@ -689,7 +689,7 @@ smb_receive_raw (
 				 * This adds up to 48 bytes.
 				 */
 
-				LOG(("SMBread: reading the first %ld bytes\n", 48));
+				D(("SMBread: reading the first %ld bytes", 48));
 
 				ASSERT( target != NULL );
 
@@ -698,7 +698,7 @@ smb_receive_raw (
 				{
 					(*error_ptr) = errno;
 
-					LOG (("recv error = %ld\n", (*error_ptr)));
+					D(("recv error = %ld", (*error_ptr)));
 
 					PROFILE_POP("SMBread");
 
@@ -713,7 +713,7 @@ smb_receive_raw (
 				if(num_bytes_received < 48)
 				{
 					/* End of file */
-					LOG (("EOF\n"));
+					SHOWMSG("EOF");
 
 					(*error_ptr) = error_end_of_file;
 
@@ -732,11 +732,11 @@ smb_receive_raw (
 				/* The buffer format must be 1. */
 				buffer_format = BVAL(target, 45);
 
-				LOG(("buffer format = %ld, should be %ld\n", buffer_format, 1));
+				D(("buffer format = %ld, should be %ld", buffer_format, 1));
 
 				if(buffer_format != 1)
 				{
-					LOG(("buffer format %ld not supported\n", buffer_format));
+					D(("buffer format %ld not supported", buffer_format));
 
 					(*error_ptr) = error_invalid_buffer_format;
 
@@ -755,11 +755,11 @@ smb_receive_raw (
 				ASSERT( count_of_bytes_to_read <= count_of_bytes_returned );
 				ASSERT( count_of_bytes_returned <= input_payload_size );
 
-				LOG(("count of bytes to read = %ld, should be <= %ld\n", count_of_bytes_to_read, input_payload_size));
+				D(("count of bytes to read = %ld, should be <= %ld", count_of_bytes_to_read, input_payload_size));
 
 				if(count_of_bytes_returned > input_payload_size)
 				{
-					LOG(("this is too much data\n"));
+					SHOWMSG("this is too much data");
 
 					(*error_ptr) = error_message_exceeds_buffer_size;
 
@@ -775,7 +775,7 @@ smb_receive_raw (
 				{
 					(*error_ptr) = errno;
 
-					LOG (("recv error = %ld\n", (*error_ptr)));
+					D(("recv error = %ld", (*error_ptr)));
 
 					PROFILE_POP("SMBread");
 
@@ -785,7 +785,7 @@ smb_receive_raw (
 				if(result < count_of_bytes_to_read)
 				{
 					/* End of file */
-					LOG (("EOF\n"));
+					SHOWMSG("EOF");
 
 					(*error_ptr) = error_end_of_file;
 
@@ -802,7 +802,7 @@ smb_receive_raw (
 
 				if(count_of_bytes_to_read < count_of_bytes_returned)
 				{
-					LOG(("fewer data available than should be delivered; setting the remainder (%ld bytes) to 0.\n", count_of_bytes_returned - count_of_bytes_to_read));
+					D(("fewer data available than should be delivered; setting the remainder (%ld bytes) to 0.", count_of_bytes_returned - count_of_bytes_to_read));
 
 					memset(&input_payload[count_of_bytes_to_read],0,count_of_bytes_returned - count_of_bytes_to_read);
 				}
@@ -812,14 +812,14 @@ smb_receive_raw (
 				 */
 				if(num_bytes_received < len)
 				{
-					LOG(("reading the remaining %ld bytes; this should never happen\n", len - num_bytes_received ));
+					D(("reading the remaining %ld bytes; this should never happen", len - num_bytes_received ));
 
 					result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received);
 					if (result < 0)
 					{
 						(*error_ptr) = errno;
 
-						LOG (("recv error = %ld\n", (*error_ptr)));
+						D(("recv error = %ld", (*error_ptr)));
 
 						PROFILE_POP("SMBread");
 
@@ -829,7 +829,7 @@ smb_receive_raw (
 					if(result < len - num_bytes_received)
 					{
 						/* End of file */
-						LOG (("EOF\n"));
+						SHOWMSG("EOF");
 
 						(*error_ptr) = error_end_of_file;
 
@@ -869,7 +869,7 @@ smb_receive_raw (
 		{
 			PROFILE_PUSH("SMB read full");
 
-			LOG(("receiving SMB message and payload in one chunk\n"));
+			SHOWMSG("receiving SMB message and payload in one chunk");
 
 			ASSERT( target != NULL );
 
@@ -878,7 +878,7 @@ smb_receive_raw (
 			{
 				(*error_ptr) = errno;
 
-				LOG (("recv error = %ld\n", (*error_ptr)));
+				D(("recv error = %ld", (*error_ptr)));
 
 				PROFILE_POP("SMB read full");
 
@@ -888,7 +888,7 @@ smb_receive_raw (
 			if(result < len)
 			{
 				/* End of file */
-				LOG (("EOF\n"));
+				SHOWMSG("EOF");
 
 				(*error_ptr) = error_end_of_file;
 
@@ -934,11 +934,11 @@ smb_receive_raw (
 				/* The buffer format must be 1. */
 				buffer_format = BVAL(target, 45);
 
-				LOG(("buffer format = %ld, should be %ld\n", buffer_format, 1));
+				D(("buffer format = %ld, should be %ld", buffer_format, 1));
 
 				if(buffer_format != 1)
 				{
-					LOG(("buffer format %ld not supported\n", buffer_format));
+					D(("buffer format %ld not supported", buffer_format));
 
 					(*error_ptr) = error_invalid_buffer_format;
 
@@ -957,11 +957,11 @@ smb_receive_raw (
 				ASSERT( count_of_bytes_to_read <= count_of_bytes_returned );
 				ASSERT( count_of_bytes_returned <= input_payload_size );
 
-				LOG(("count of bytes to read = %ld, should be <= %ld\n", count_of_bytes_to_read, input_payload_size));
+				D(("count of bytes to read = %ld, should be <= %ld", count_of_bytes_to_read, input_payload_size));
 
 				if(count_of_bytes_returned > input_payload_size)
 				{
-					LOG(("this is too much data\n"));
+					SHOWMSG("this is too much data");
 
 					(*error_ptr) = error_message_exceeds_buffer_size;
 
@@ -978,7 +978,7 @@ smb_receive_raw (
 
 				if(count_of_bytes_to_read < count_of_bytes_returned)
 				{
-					LOG(("fewer data available than should be delivered; setting the remainder (%ld bytes) to 0.\n", count_of_bytes_returned - count_of_bytes_to_read));
+					D(("fewer data available than should be delivered; setting the remainder (%ld bytes) to 0.", count_of_bytes_returned - count_of_bytes_to_read));
 
 					memset(&input_payload[count_of_bytes_to_read],0,count_of_bytes_returned - count_of_bytes_to_read);
 				}
@@ -998,7 +998,7 @@ smb_receive_raw (
 		{
 			(*error_ptr) = errno;
 
-			LOG (("recv error = %ld\n", (*error_ptr)));
+			D(("recv error = %ld", (*error_ptr)));
 
 			PROFILE_POP("SMB read single buffer");
 
@@ -1008,7 +1008,7 @@ smb_receive_raw (
 		if(result < len)
 		{
 			/* End of file */
-			LOG (("EOF\n"));
+			SHOWMSG("EOF");
 
 			(*error_ptr) = error_end_of_file;
 
@@ -1071,7 +1071,7 @@ smb_receive (
 
 	if (result < 0)
 	{
-		LOG (("receive error: %ld\n", (*error_ptr)));
+		D(("receive error: %ld", (*error_ptr)));
 		goto out;
 	}
 
@@ -1147,7 +1147,7 @@ smb_receive_trans2 (
 
 	if ((total_data > server->max_recv) || (total_param > server->max_recv))
 	{
-		LOG (("data/param too long\n"));
+		SHOWMSG("data/param too long");
 
 		(*error_ptr) = error_data_exceeds_buffer_size;
 
@@ -1163,7 +1163,7 @@ smb_receive_trans2 (
 		data = malloc (total_data);
 		if (data == NULL)
 		{
-			LOG (("could not alloc data area\n"));
+			SHOWMSG("could not alloc data area");
 
 			(*error_ptr) = ENOMEM;
 
@@ -1180,7 +1180,7 @@ smb_receive_trans2 (
 		param = malloc(total_param);
 		if (param == NULL)
 		{
-			LOG (("could not alloc param area\n"));
+			SHOWMSG("could not alloc param area");
 
 			(*error_ptr) = ENOMEM;
 
@@ -1189,7 +1189,7 @@ smb_receive_trans2 (
 		}
 	}
 
-	LOG (("total_data/total_param: %ld/%ld\n", total_data, total_param));
+	D(("total_data/total_param: %ld/%ld", total_data, total_param));
 
 	param_len = 0;
 	data_len = 0;
@@ -1209,7 +1209,7 @@ smb_receive_trans2 (
 
 		if (parameter_displacement + parameter_count > total_param)
 		{
-			LOG (("invalid parameters\n"));
+			SHOWMSG("invalid parameters");
 
 			(*error_ptr) = error_invalid_parameter_size;
 
@@ -1224,7 +1224,7 @@ smb_receive_trans2 (
 
 		if (data_displacement + data_count > total_data)
 		{
-			LOG (("invalid data block\n"));
+			SHOWMSG("invalid data block");
 
 			(*error_ptr) = error_invalid_parameter_size;
 
@@ -1237,12 +1237,12 @@ smb_receive_trans2 (
 
 		data_len += data_count;
 
-		LOG (("data count/parameter count: %ld/%ld\n", data_count, parameter_count));
+		D(("data count/parameter count: %ld/%ld", data_count, parameter_count));
 
 		/* parse out the total lengths again - they can shrink! */
 		if (total_data_count > total_data || total_parameter_count > total_param)
 		{
-			LOG (("data/params grew!\n"));
+			SHOWMSG("data/params grew!");
 
 			(*error_ptr) = error_data_exceeds_buffer_size;
 
@@ -1326,7 +1326,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 
 	if(server->mount_data.fd < 0)
 	{
-		LOG(("network socket needs to be opened\n"));
+		SHOWMSG("network socket needs to be opened");
 
 		result = socket (AF_INET, SOCK_STREAM, 0);
 		if (result < 0)
@@ -1341,7 +1341,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		server->mount_data.fd = result;
 	}
 
-	LOG(("connecting to server %s:%ld with socket %ld\n",
+	D(("connecting to server %s:%ld with socket %ld",
 		Inet_NtoA(server->mount_data.addr.sin_addr.s_addr),
 		ntohs(server->mount_data.addr.sin_port),
 		server->mount_data.fd));
@@ -1381,7 +1381,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		 */
 		connect (server->mount_data.fd, (struct sockaddr *)&server->mount_data.addr, sizeof(struct sockaddr_in));
 
-		LOG(("will wait for up to %ld seconds for connection attempt to succeed\n",server->timeout));
+		D(("will wait for up to %ld seconds for connection attempt to succeed",server->timeout));
 
 		/* Wait for the connection status to change (success/failure), or until
 		 * the timeout has elapsed.
@@ -1408,7 +1408,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 				/* Connection could not be made. */
 				else
 				{
-					LOG(("connection could not be established (error=%ld)\n",errno));
+					D(("connection could not be established (error=%ld)",errno));
 
 					(*error_ptr) = errno;
 
@@ -1418,7 +1418,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 			/* Well, that could happen, too. */
 			else
 			{
-				LOG(("connection could not be established (error=%ld)\n",errno));
+				D(("connection could not be established (error=%ld)",errno));
 
 				(*error_ptr) = errno;
 				result = -1;
@@ -1427,7 +1427,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		/* Connection attempt timed out? */
 		else if (result == 0)
 		{
-			LOG(("connection could not be established (timeout)\n"));
+			SHOWMSG("connection could not be established (timeout)");
 
 			(*error_ptr) = EWOULDBLOCK;
 			result = -1;
@@ -1435,7 +1435,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		/* Well, that could happen, too. */
 		else /* if (result < 0) */
 		{
-			LOG(("connection could not be established (error=%ld)\n",errno));
+			D(("connection could not be established (error=%ld)",errno));
 
 			(*error_ptr) = errno;
 		}
@@ -1448,7 +1448,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		{
 			server->state = CONN_INVALID;
 
-			LOG(("connection is invalid.\n"));
+			SHOWMSG("connection is invalid.");
 			goto out;
 		}
 	}
@@ -1460,7 +1460,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 		result = connect (server->mount_data.fd, (struct sockaddr *)&server->mount_data.addr, sizeof(struct sockaddr_in));
 		if(result < 0)
 		{
-			LOG(("connect() has failed (errno=%ld)\n",errno));
+			D(("connect() has failed (errno=%ld)",errno));
 
 			server->state = CONN_INVALID;
 
@@ -1499,14 +1499,14 @@ smb_connect (struct smb_server *server, int * error_ptr)
 
 		tv.tv_secs = server->timeout;
 
-		LOG(("server timeout = %ld seconds\n", server->timeout));
+		D(("server timeout = %ld seconds", server->timeout));
 
 		setsockopt(server->mount_data.fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv));
 		setsockopt(server->mount_data.fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));
 	}
 	else
 	{
-		LOG(("no server read/write/connect timeout was set\n"));
+		SHOWMSG("no server read/write/connect timeout was set");
 	}
 
  out:
@@ -1517,7 +1517,7 @@ smb_connect (struct smb_server *server, int * error_ptr)
 }
 
 /* If there was a network error, or data was left unread,
- * the best option is to the close server connection and
+ * the best option is to close the server connection and
  * reopen it again.
  *
  * Here's where we decide whether closing the connection
@@ -1588,7 +1588,7 @@ smb_request (
 
 	if ((sock_fd < 0) || (buffer == NULL))
 	{
-		LOG (("Bad server!\n"));
+		SHOWMSG("Bad server!");
 
 		(*error_ptr) = error_server_setup_incomplete;
 
@@ -1598,7 +1598,7 @@ smb_request (
 
 	if (server->state != CONN_VALID)
 	{
-		LOG (("Connection state is invalid\n"));
+		SHOWMSG("Connection state is invalid");
 
 		(*error_ptr) = error_server_connection_invalid;
 
@@ -1622,7 +1622,7 @@ smb_request (
 		/* Send SMB message header and payload separately? */
 		if(len > server->smb_write_threshold)
 		{
-			LOG(("sending SMB message and payload separately\n"));
+			SHOWMSG("sending SMB message and payload separately");
 
 			len -= payload_size;
 		}
@@ -1635,7 +1635,7 @@ smb_request (
 		 */
 		else
 		{
-			LOG(("sending SMB message and payload in one chunk\n"));
+			SHOWMSG("sending SMB message and payload in one chunk");
 
 			memcpy(&buffer[len - payload_size], output_payload, payload_size);
 
@@ -1644,7 +1644,7 @@ smb_request (
 		}
 	}
 
-	LOG (("len = %ld, cmd = 0x%lx, input_payload=0x%08lx, output_payload=0x%08lx, payload_size=%ld\n",
+	D(("len = %ld, cmd = 0x%lx, input_payload=0x%08lx, output_payload=0x%08lx, payload_size=%ld",
 		len,
 		buffer[8],
 		(unsigned long)input_payload,
@@ -1661,12 +1661,12 @@ smb_request (
 		/* Use two send() calls for header and payload? */
 		if(!server->scatter_gather)
 		{
-			LOG(("using two send() calls\n"));
+			SHOWMSG("using two send() calls");
 
 			result = send_all (sock_fd, buffer, len);
 			if (result < 0)
 			{
-				LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno));
+				D(("send() for %ld bytes failed (errno=%ld)", len, errno));
 
 				(*error_ptr) = errno;
 
@@ -1676,7 +1676,7 @@ smb_request (
 			result = send_all (sock_fd, output_payload, payload_size);
 			if (result < 0)
 			{
-				LOG(("payload send() for %ld bytes failed (errno=%ld)\n", payload_size, errno));
+				D(("payload send() for %ld bytes failed (errno=%ld)", payload_size, errno));
 
 				(*error_ptr) = errno;
 
@@ -1691,7 +1691,7 @@ smb_request (
 			struct msghdr msg;
 			struct iovec iov[2];
 
-			LOG(("using sendmsg() for %ld+%ld = %ld bytes\n", len, payload_size, len+payload_size));
+			D(("using sendmsg() for %ld+%ld = %ld bytes", len, payload_size, len+payload_size));
 
 			memset(&msg,0,sizeof(msg));
 
@@ -1712,7 +1712,7 @@ smb_request (
 
 			if (result < 0)
 			{
-				LOG(("sendmsg() for %ld+%ld bytes failed (errno=%ld)\n", len, payload_size, errno));
+				D(("sendmsg() for %ld+%ld bytes failed (errno=%ld)", len, payload_size, errno));
 
 				(*error_ptr) = errno;
 
@@ -1725,7 +1725,7 @@ smb_request (
 		result = send_all (sock_fd, buffer, len);
 		if (result < 0)
 		{
-			LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno));
+			D(("send() for %ld bytes failed (errno=%ld)", len, errno));
 
 			(*error_ptr) = errno;
 
@@ -1740,7 +1740,7 @@ smb_request (
 	if (result < 0)
 		smb_check_server_connection(server,(*error_ptr));
 
-	LOG (("result = %ld\n", result));
+	D(("result = %ld", result));
 
 	return (result);
 }
@@ -1766,7 +1766,7 @@ smb_trans2_request (
 
 	if (server->state != CONN_VALID)
 	{
-		LOG (("Connection state is invalid\n"));
+		SHOWMSG("Connection state is invalid");
 
 		(*error_ptr) = error_server_connection_invalid;
 
@@ -1779,7 +1779,7 @@ smb_trans2_request (
 	 */
 	len = NETBIOS_HEADER_SIZE + smb_len (buffer);
 
-	LOG (("len = %ld cmd = 0x%02lx\n", len, buffer[8]));
+	D(("len = %ld cmd = 0x%02lx", len, buffer[8]));
 
 	#if defined(DUMP_SMB)
 	dump_netbios_header(__FILE__,__LINE__,buffer,NULL,0);
@@ -1789,7 +1789,7 @@ smb_trans2_request (
 	result = send_all (sock_fd, buffer, len);
 	if (result < 0)
 	{
-		LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno));
+		D(("send() for %ld bytes failed (errno=%ld)", len, errno));
 
 		(*error_ptr) = errno;
 		goto out;
@@ -1802,7 +1802,7 @@ smb_trans2_request (
 	if (result < 0)
 		smb_check_server_connection(server,(*error_ptr));
 
-	LOG (("result = %ld\n", result));
+	D(("result = %ld", result));
 
 	return result;
 }
@@ -1822,7 +1822,7 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_
 
 	if (server->state != CONN_VALID)
 	{
-		LOG (("Connection state is invalid\n"));
+		SHOWMSG("Connection state is invalid");
 
 		(*error_ptr) = error_server_connection_invalid;
 
@@ -1835,9 +1835,9 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_
 	 */
 	len = NETBIOS_HEADER_SIZE + smb_len (buffer);
 
-	LOG (("len = %ld cmd = 0x%02lx\n", len, buffer[8]));
-	LOG (("target=%lx, max_len=%ld\n", (unsigned int) target, max_len));
-	LOG (("buffer=%lx, sock=%lx\n", (unsigned int) buffer, (unsigned int) sock_fd));
+	D(("len = %ld cmd = 0x%02lx", len, buffer[8]));
+	D(("target=%lx, max_len=%ld", (unsigned int) target, max_len));
+	D(("buffer=%lx, sock=%lx", (unsigned int) buffer, (unsigned int) sock_fd));
 
 	#if defined(DUMP_SMB)
 	dump_netbios_header(__FILE__,__LINE__,buffer,NULL,0);
@@ -1848,7 +1848,7 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_
 	result = send_all (sock_fd, buffer, len);
 	if (result < 0)
 	{
-		LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno));
+		D(("send() for %ld bytes failed (errno=%ld)", len, errno));
 
 		(*error_ptr) = errno;
 
@@ -1863,7 +1863,7 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_
 	if (result < 0)
 		smb_check_server_connection(server,(*error_ptr));
 
-	LOG (("result = %ld\n", result));
+	D(("result = %ld", result));
 
 	return result;
 }
@@ -1880,7 +1880,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 
 	if (server->state != CONN_VALID)
 	{
-		LOG (("Connection state is invalid\n"));
+		SHOWMSG("Connection state is invalid");
 
 		(*error_ptr) = error_server_connection_invalid;
 
@@ -1903,13 +1903,13 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 	/* Use two send() calls to transmit header and data? */
 	if(!server->scatter_gather)
 	{
-		LOG(("using two send() calls\n"));
+		SHOWMSG("using two send() calls");
 
 		/* Send the NetBIOS header. */
 		result = send_all (sock_fd, nb_header, NETBIOS_HEADER_SIZE);
 		if(result < 0)
 		{
-			LOG(("send() for %ld bytes failed (errno=%ld)\n", NETBIOS_HEADER_SIZE, errno));
+			D(("send() for %ld bytes failed (errno=%ld)", NETBIOS_HEADER_SIZE, errno));
 
 			(*error_ptr) = errno;
 
@@ -1920,7 +1920,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 		result = send_all (sock_fd, source, length);
 		if(result < 0)
 		{
-			LOG(("send() for %ld bytes failed (errno=%ld)\n", length, errno));
+			D(("send() for %ld bytes failed (errno=%ld)", length, errno));
 
 			(*error_ptr) = errno;
 
@@ -1935,7 +1935,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 		struct msghdr msg;
 		struct iovec iov[2];
 
-		LOG(("using sendmsg() for %ld+%ld = %ld bytes\n", NETBIOS_HEADER_SIZE, length, NETBIOS_HEADER_SIZE+length));
+		D(("using sendmsg() for %ld+%ld = %ld bytes", NETBIOS_HEADER_SIZE, length, NETBIOS_HEADER_SIZE+length));
 
 		memset(&msg,0,sizeof(msg));
 
@@ -1956,7 +1956,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 
 		if (result < 0)
 		{
-			LOG(("sendmsg() for %ld+%ld bytes failed (errno=%ld)\n", NETBIOS_HEADER_SIZE, length, errno));
+			D(("sendmsg() for %ld+%ld bytes failed (errno=%ld)", NETBIOS_HEADER_SIZE, length, errno));
 
 			(*error_ptr) = errno;
 
@@ -1973,7 +1973,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 	}
 	else
 	{
-		LOG(("not waiting for server to respond\n"));
+		SHOWMSG("not waiting for server to respond");
 	}
 
 	result = length;
@@ -1983,7 +1983,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
 	if (result < 0)
 		smb_check_server_connection(server,(*error_ptr));
 
-	LOG (("result = %ld\n", result));
+	D(("result = %ld", result));
 
 	return result;
 }