Updated to version 1.152

Please keep in mind that this is still a development version and might surprise you (not necessarily in a good way).

Do not let me discourage you to build and test this version, although there will be some risks involved such as data corruption or loss of data.
This commit is contained in:
obarthel
2018-06-11 20:16:56 +02:00
parent 7e518c9064
commit 593e22abb2
8 changed files with 330 additions and 146 deletions
+44
View File
@@ -1996,3 +1996,47 @@ smbfs 1.150 (10.6.2018)
- If reading the keepalive packets sent by the server turns out to
detect a broken server connection, we now shut it down on our
side rather than waiting for a retry.
smbfs 1.151 (11.6.2018)
- The WORKGROUP parameter is no longer mandatory. If you omit it,
then the default text "WORKGROUP" will be used.
- The UNICODE parameter now expects ON/OFF as arguments rather than
being a simple enable switch. Note that the default is UNICODE=ON
now, which means that if both server and client support Unicode,
then smbfs will use it and ignore the TRANSLATE, CP437 and CP850
parameters.
- Added the PROTOCOL parameter which can be either NT1 or CORE,
with NT1 being the default. If you use PROTOCOL=CORE, then none
of the new SMB commands (introduced in 1994) added to smbfs
will be used, which might make smbfs work more robustly with
certain servers.
- smbfs now only asks the SMB server for write access to a file
or directory if that file is to be written to, or if the
file/directory attributes are to be modified. I double-checked
that these constraints are followed consistently.
- Reworked the logic for Open() with MODE_OLDFILE/MODE_NEWFILE
and MODE_UPDATE. MODE_OLDFILE will open the file for read
access and implies a shared lock. MODE_NEWFILE will open the
file for read/write access and truncate it to 0 bytes, creating
it if it does not yet exist, and implies an exclusive lock.
MODE_UPDATE will open the file for read/write access and
implies an exclusive lock.
- When opening a "file" smbfs now checks if the file is really
a file and not a directory. The SMB_COM_NT_CREATE_ANDX and
SMB_COM_OPEN commands can be told not to open a directory if
a file is expected, but the current smbfs implementation makes
it a wee bit too difficult to plug this into the API :-/
Well, we may see about this later.
smbfs 1.152 (11.6.2018)
- Ouch. Forgot that pretty much all the core functions were
still not supporting Unicode mode. Fixed.
+3
View File
@@ -76,6 +76,9 @@ struct smb_server
/* olsen (2018-06-01): Enable Unicode support if the server supports it. */
int use_unicode;
/* olsen (2018-06-11): Prefer SMB core protocol commands over NT1 commands. */
int prefer_core_protocol;
};
#endif
+118 -81
View File
@@ -151,7 +151,7 @@ static ULONG stack_usage_exit(const struct StackSwapStruct * stk);
static LONG CVSPrintf(const TEXT * format_string, APTR args);
static void VSPrintf(STRPTR buffer, const TEXT * formatString, APTR args);
static void cleanup(void);
static BOOL setup(const TEXT * program_name, const TEXT * service, const TEXT * workgroup, const TEXT * username, STRPTR opt_password, BOOL opt_changecase, const TEXT * opt_clientname, const TEXT * opt_servername, int opt_cachesize, 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_write_raw, BOOL opt_write_behind, BOOL opt_prefer_read_raw, const TEXT * device_name, const TEXT * volume_name, const TEXT * translation_file);
static BOOL setup(const TEXT * program_name, const TEXT * service, const TEXT * workgroup, const TEXT * username, STRPTR opt_password, BOOL opt_changecase, const TEXT * opt_clientname, const TEXT * opt_servername, int opt_cachesize, 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_prefer_write_raw, BOOL opt_write_behind, BOOL opt_prefer_read_raw, const TEXT * device_name, const TEXT * volume_name, const TEXT * translation_file);
static void file_system_handler(const TEXT * device_name, const TEXT * volume_name, const TEXT * service_name);
/****************************************************************************/
@@ -556,11 +556,12 @@ main(void)
NUMBER Timeout;
NUMBER TimeZoneOffset;
NUMBER DSTOffset;
KEY Protocol;
SWITCH NetBIOSTransport;
SWITCH PreferWriteRaw;
SWITCH WriteBehind;
SWITCH PreferReadRaw;
SWITCH Unicode;
KEY Unicode;
SWITCH UTF8;
SWITCH CP437;
SWITCH CP850;
@@ -590,11 +591,12 @@ main(void)
"TIMEOUT/N/K,"
"TZ=TIMEZONEOFFSET/N/K,"
"DST=DSTOFFSET/N/K,"
"PROTOCOL/K,"
"NETBIOS/S,"
"PREFERWRITERAW/S,"
"WRITEBEHIND/S,"
"PREFERREADRAW/S,"
"UNICODE/S,"
"UNICODE/K,"
"UTF8/S,"
"CP437/S,"
"CP850/S,"
@@ -615,6 +617,7 @@ main(void)
LONG cache_size = 0;
LONG max_transmit = -1;
LONG timeout = 0;
char env_protocol[8];
char env_workgroup_name[17];
char env_user_name[64];
char env_password[64];
@@ -701,11 +704,6 @@ main(void)
{
str = env_workgroup_name;
}
else
{
report_error("Required 'WORKGROUP' parameter was not provided.");
goto out;
}
}
args.Workgroup = str;
@@ -835,6 +833,15 @@ main(void)
args.DSTOffset = &dst_number;
}
str = FindToolType(Icon->do_ToolTypes,"PROTOCOL");
if(str == NULL)
{
if(GetVar("smbfs_protocol",env_protocol,sizeof(env_protocol),0) > 0)
str = env_protocol;
}
args.Protocol = str;
if(FindToolType(Icon->do_ToolTypes,"NETBIOS") != NULL)
args.NetBIOSTransport = TRUE;
@@ -857,8 +864,9 @@ main(void)
}
else
{
if (FindToolType(Icon->do_ToolTypes,"UNICODE") != NULL)
args.Unicode = TRUE;
str = FindToolType(Icon->do_ToolTypes,"UNICODE");
if (str != NULL)
args.Unicode = str;
else if (FindToolType(Icon->do_ToolTypes,"UTF8") != NULL)
args.UTF8 = TRUE;
else if (FindToolType(Icon->do_ToolTypes,"CP437") != NULL)
@@ -906,12 +914,6 @@ main(void)
timeout = number;
}
if(args.Workgroup == NULL)
{
report_error("Required 'WORKGROUP' parameter was not provided.");
goto out;
}
if(args.Service == NULL)
{
report_error("'SERVICE' parameter needs an argument.");
@@ -939,11 +941,6 @@ main(void)
{
args.Workgroup = env_workgroup_name;
}
else
{
report_error("Required 'WORKGROUP' parameter was not provided.");
goto out;
}
}
if(args.UserName == NULL)
@@ -961,6 +958,12 @@ main(void)
args.Password = env_password;
}
if(args.Protocol == NULL)
{
if(GetVar("smbfs_protocol",env_protocol,sizeof(env_protocol),0) > 0)
args.Protocol = env_protocol;
}
if(args.Service != NULL)
{
const TEXT * name = FilePart(program_name);
@@ -991,6 +994,26 @@ main(void)
if(args.DeviceName == NULL && args.VolumeName == NULL)
args.DeviceName = "SMBFS";
/* Restrict the command set which smbfs uses? */
if(args.Protocol == NULL)
args.Protocol = "NT1";
if(Stricmp(args.Protocol,"NT1") != SAME && Stricmp(args.Protocol,"CORE") != SAME)
{
report_error("'PROTOCOL' parameter must be either 'NT1' or 'CORE'.");
goto out;
}
/* Disable Unicode support for path names, etc.? */
if(args.Unicode == NULL)
args.Unicode = "ON";
if(Stricmp(args.Unicode,"OFF") != SAME && Stricmp(args.Unicode,"ON") != SAME)
{
report_error("'UNICODE' parameter must be either 'ON' or 'OFF'.");
goto out;
}
/* Code page based translation using a file disables
* UTF-8 and built-in CP437 and CP850 translation.
*/
@@ -1026,6 +1049,22 @@ main(void)
OmitHidden = (BOOL)args.OmitHidden;
TranslateUTF8 = (BOOL)args.UTF8;
/* You don't need to provide a specific workgroup name. smbfs will
* work perfectly find with modern (and somewhat older) SMB implementations
* if the workgroup name does not match the server's workgroup name.
* But a workgroup name is still mandatory because it's required as part
* of the protocol which sets up the connection between client and
* server.
*
* It all boils down to this: if you don't choose a workgroup name,
* smbfs will use a default of "WORKGROUP".
*/
if(args.Workgroup == NULL)
{
strlcpy(env_workgroup_name,"WORKGROUP",sizeof(env_workgroup_name));
args.Workgroup = env_workgroup_name;
}
#if DEBUG
{
if(args.DebugFile != NULL)
@@ -1114,7 +1153,8 @@ main(void)
args.TimeZoneOffset,
args.DSTOffset,
!args.NetBIOSTransport, /* Use raw SMB transport instead of NetBIOS transport? */
args.Unicode,
Stricmp(args.Unicode,"OFF") != SAME,
Stricmp(args.Protocol,"CORE") == SAME,
args.PreferWriteRaw,
args.WriteBehind,
args.PreferReadRaw,
@@ -1610,6 +1650,8 @@ get_time_zone_delta(void)
seconds = 0;
}
D(("time zone offset: %ld + %ld = %ld",seconds,DSTOffset,seconds + DSTOffset));
return(seconds + DSTOffset);
}
@@ -1626,7 +1668,7 @@ get_current_time(void)
GetSysTime((APTR)&tv);
result = UNIX_TIME_OFFSET + get_time_zone_delta() + tv.tv_secs;
result = tv.tv_secs + UNIX_TIME_OFFSET + get_time_zone_delta();
return(result);
}
@@ -2698,6 +2740,7 @@ setup(
LONG * opt_dst_offset,
BOOL opt_raw_smb,
BOOL opt_unicode,
BOOL opt_prefer_core_protocol,
BOOL opt_prefer_write_raw,
BOOL opt_write_behind,
BOOL opt_prefer_read_raw,
@@ -2750,11 +2793,22 @@ setup(
{
TimeZoneOffset = -(*opt_time_zone_offset);
OverrideLocaleTimeZone = TRUE;
SHOWVALUE(TimeZoneOffset);
}
else
{
if(Locale != NULL)
SHOWVALUE(Locale->loc_GMTOffset);
}
if(opt_dst_offset != NULL)
{
DSTOffset = -60 * (*opt_dst_offset);
SHOWVALUE(DSTOffset);
}
memset(&TimerRequest,0,sizeof(TimerRequest));
if(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)&TimerRequest,0) != OK)
@@ -2879,6 +2933,7 @@ setup(
opt_timeout,
opt_raw_smb,
opt_unicode,
opt_prefer_core_protocol,
opt_prefer_write_raw,
opt_write_behind,
opt_prefer_read_raw,
@@ -4138,7 +4193,7 @@ Action_DeleteObject(
D(("full_name = '%s'",escape_name(full_name)));
if(smba_open(ServerData,full_name,open_writable,open_dont_truncate,&file,&error) < 0)
if(smba_open(ServerData,full_name,open_read_only,open_dont_truncate,&file,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
@@ -4330,7 +4385,7 @@ Action_CreateDir(
ln->ln_FullName = full_name;
ln->ln_LastUser = user;
if(smba_open(ServerData,dir_name,open_writable,open_dont_truncate,&dir,&error) < 0)
if(smba_open(ServerData,dir_name,open_read_only,open_dont_truncate,&dir,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
@@ -4349,7 +4404,7 @@ Action_CreateDir(
D(("full_name = '%s'",escape_name(full_name)));
if(smba_open(ServerData,full_name,open_writable,open_dont_truncate,&ln->ln_File,&error) < 0)
if(smba_open(ServerData,full_name,open_read_only,open_dont_truncate,&ln->ln_File,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
@@ -5220,7 +5275,9 @@ Action_ExamineObject(
goto out;
}
seconds = st.mtime - UNIX_TIME_OFFSET - get_time_zone_delta();
seconds = st.mtime;
seconds -= UNIX_TIME_OFFSET + get_time_zone_delta();
if(seconds < 0)
seconds = 0;
@@ -5514,7 +5571,9 @@ dir_scan_callback_func_exnext(
fib->fib_Protection |= FIBF_ARCHIVE;
/* If modification time is 0 use creation time instead (cyfm 2009-03-18). */
seconds = (st->mtime == 0 ? st->ctime : st->mtime) - UNIX_TIME_OFFSET - get_time_zone_delta();
seconds = (st->mtime == 0 ? st->ctime : st->mtime);
seconds -= UNIX_TIME_OFFSET + get_time_zone_delta();
if(seconds < 0)
seconds = 0;
@@ -5819,7 +5878,9 @@ dir_scan_callback_func_exall(
LONG seconds;
/* If modification time is 0 use creation time instead (cyfm 2009-03-18). */
seconds = (st->mtime == 0 ? st->ctime : st->mtime) - UNIX_TIME_OFFSET - get_time_zone_delta();
seconds = (st->mtime == 0 ? st->ctime : st->mtime);
seconds -= UNIX_TIME_OFFSET + get_time_zone_delta();
if(seconds < 0)
seconds = 0;
@@ -6138,8 +6199,8 @@ Action_Find(
struct FileNode * fn = NULL;
const TEXT * parent_name;
TEXT name[MAX_FILENAME_LEN+1];
BOOL create_new_file;
STRPTR temp = NULL;
smba_stat_t st;
int error;
ENTER();
@@ -6222,7 +6283,7 @@ Action_Find(
fn->fn_Handle = fh;
fn->fn_Magic = ID_SMB_DISK;
fn->fn_FullName = full_name;
fn->fn_Mode = (action == ACTION_FINDOUTPUT) ? EXCLUSIVE_LOCK : SHARED_LOCK;
fn->fn_Mode = (action == ACTION_FINDINPUT) ? SHARED_LOCK : EXCLUSIVE_LOCK;
error = check_access_mode_collision(full_name,fn->fn_Mode);
if(error != OK)
@@ -6230,53 +6291,8 @@ Action_Find(
D(("full_name = '%s'",escape_name(full_name)));
/* Create a new file, or truncate an existing file? */
if(action == ACTION_FINDOUTPUT)
{
/* Definitely create a new file. */
create_new_file = TRUE;
}
else if (action == ACTION_FINDINPUT)
{
/* Open an existing file for reading. */
create_new_file = FALSE;
}
else if (action == ACTION_FINDUPDATE)
{
smba_file_t * file = NULL;
int ignored_error;
smba_stat_t st;
if(smba_open(ServerData,full_name,open_read_only,open_dont_truncate,&file,&ignored_error) == OK &&
smba_getattr(file,&st,&ignored_error) == OK)
{
/* File apparently opens OK and information on it
* is available, don't try to replace it.
*/
create_new_file = FALSE;
}
else
{
/* We try to ignore the error here and assume
* that the remainder of the file opening
* procedure will produce a useful error
* report. In the mean time, assume that the
* file needs to be created.
*/
create_new_file = TRUE;
}
if(file != NULL)
smba_close(ServerData,file);
}
else
{
/* What's that? */
error = ERROR_ACTION_NOT_KNOWN;
goto out;
}
/* Create a new file? */
if(create_new_file)
{
STRPTR dir_name,base_name;
smba_file_t * dir;
@@ -6297,7 +6313,7 @@ Action_Find(
SHOWMSG("creating a file; finding parent path first");
D(("dir_name = '%s'",escape_name(dir_name)));
if(smba_open(ServerData,dir_name,open_writable,open_dont_truncate,&dir,&error) < 0)
if(smba_open(ServerData,dir_name,open_read_only,open_dont_truncate,&dir,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
@@ -6325,13 +6341,32 @@ Action_Find(
smba_close(ServerData,dir);
}
/* Now for the remainder... */
if(smba_open(ServerData,full_name,action != ACTION_FINDINPUT,create_new_file,&fn->fn_File,&error) < 0)
/* Open the file for read access if ACTION_FINDINPUT is used,
* and for write access for ACTION_FINDOUTPUT/ACTION_FINDUPDATE.
*/
if(smba_open(ServerData,full_name,(action != ACTION_FINDINPUT),open_dont_truncate,&fn->fn_File,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
}
/* Make sure that we ended opening a file, and not a directory.
* Embarrassing questions might otherwise be asked later...
*/
if(smba_getattr(fn->fn_File,&st,&error) < 0)
{
error = map_errno_to_ioerr(error);
goto out;
}
if(st.is_dir)
{
D(("ouch: '%s' is a directory, not a file",escape_name(full_name)));
error = ERROR_OBJECT_WRONG_TYPE;
goto out;
}
fh->fh_Arg1 = (LONG)fn;
AddTail((struct List *)&FileList,(struct Node *)fn);
@@ -6951,7 +6986,9 @@ Action_ExamineFH(
fib->fib_Protection |= FIBF_ARCHIVE;
/* If modification time is 0 use creation time instead (cyfm 2009-03-18). */
seconds = (st.mtime == 0 ? st.ctime : st.mtime) - UNIX_TIME_OFFSET - get_time_zone_delta();
seconds = (st.mtime == 0 ? st.ctime : st.mtime);
seconds -= UNIX_TIME_OFFSET + get_time_zone_delta();
if(seconds < 0)
seconds = 0;
+125 -29
View File
@@ -1162,7 +1162,7 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
truncate_file = FALSE;
}
if (server->protocol >= PROTOCOL_NT1)
if (!server->prefer_core_protocol && server->protocol >= PROTOCOL_NT1)
{
dword desired_access;
dword share_access;
@@ -1336,14 +1336,18 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
entry->opened = TRUE;
entry->writable = writable;
goto out;
}
else
{
word access_and_share_modes;
int path_size;
ASSERT( smb_payload_size(server, 2, 2 + len) >= 0 );
if(server->unicode_enabled)
path_size = 1 + 2 * (len+1);
else
path_size = 1 + len+1;
ASSERT( smb_payload_size(server, 2, path_size) >= 0 );
SHOWMSG("using the old SMB_COM_OPEN");
@@ -1354,10 +1358,19 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
else
access_and_share_modes = SMB_OPEN_SHARE_DENY_NOTHING|SMB_OPEN_ACCESS_READ_ONLY;
p = smb_setup_header (server, SMBopen, 2, 2 + len);
p = smb_setup_header (server, SMBopen, 2, path_size);
WSET (buf, smb_vwv0, access_and_share_modes);
WSET (buf, smb_vwv1, SMB_FILE_ATTRIBUTE_HIDDEN|SMB_FILE_ATTRIBUTE_SYSTEM|SMB_FILE_ATTRIBUTE_DIRECTORY);
smb_encode_ascii (p, pathname, len);
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,2 * (len+1),pathname,len);
}
else
{
smb_encode_ascii (p, pathname, len);
}
result = smb_request_ok (server, SMBopen, 7, 0, error_ptr);
if (result < 0)
@@ -1926,15 +1939,30 @@ smb_proc_create (struct smb_server *server, const char *path, int len, struct sm
int result;
char *p;
char *buf = server->transmit_buffer;
int path_size;
if(server->unicode_enabled)
path_size = 1 + 2 * (len + 1);
else
path_size = 1 + len + 1;
retry:
ASSERT( smb_payload_size(server, 3, len + 2) >= 0 );
ASSERT( smb_payload_size(server, 3, path_size) >= 0 );
p = smb_setup_header (server, SMBcreate, 3, len + 2);
p = smb_setup_header (server, SMBcreate, 3, path_size);
WSET (buf, smb_vwv0, entry->attr);
DSET (buf, smb_vwv1, local_time);
smb_encode_ascii (p, path, len);
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,2 * (len+1),path,len);
}
else
{
smb_encode_ascii (p, path, len);
}
result = smb_request_ok (server, SMBcreate, 1, 0, error_ptr);
if (result < 0)
@@ -2096,11 +2124,11 @@ smb_proc_mkdir (struct smb_server *server, const char *path, const int len, int
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,path_size,path,len);
(void) copy_latin1_to_utf16le(p,path_size,path,len);
}
else
{
smb_encode_ascii (p, path, len);
(void) smb_encode_ascii (p, path, len);
}
result = smb_request_ok (server, SMBmkdir, 0, 0, error_ptr);
@@ -2137,11 +2165,11 @@ smb_proc_rmdir (struct smb_server *server, const char *path, const int len, int
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,path_size,path,len);
(void) copy_latin1_to_utf16le(p,path_size,path,len);
}
else
{
smb_encode_ascii (p, path, len);
(void) smb_encode_ascii (p, path, len);
}
result = smb_request_ok (server, SMBrmdir, 0, 0, error_ptr);
@@ -2181,11 +2209,11 @@ smb_proc_unlink (struct smb_server *server, const char *path, const int len, int
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,path_size,path,len);
(void) copy_latin1_to_utf16le(p,path_size,path,len);
}
else
{
smb_encode_ascii (p, path, len);
(void) smb_encode_ascii (p, path, len);
}
result = smb_request_ok (server, SMBunlink, 0, 0, error_ptr);
@@ -2214,6 +2242,7 @@ smb_proc_trunc (struct smb_server *server, word fid, dword length, int * error_p
WSET (buf, smb_vwv1, 0);
DSET (buf, smb_vwv2, length);
WSET (buf, smb_vwv4, 0);
smb_encode_ascii (p, "", 0);
result = smb_request_ok (server, SMBwrite, 1, 0, error_ptr);
@@ -2281,6 +2310,8 @@ smb_proc_readdir_short (struct smb_server *server, const char *path, int fpos, i
char status[SMB_STATUS_SIZE];
int entries_asked = (server->max_recv - 100) / SMB_DIRINFO_SIZE;
int path_len = strlen (path);
int mask_len;
int mask_size;
char * mask;
mask = malloc(path_len + 4 + 1);
@@ -2295,6 +2326,13 @@ smb_proc_readdir_short (struct smb_server *server, const char *path, int fpos, i
memcpy(mask, path, path_len);
memcpy(&mask[path_len], "\\*.*", 5); /* Length includes terminating NUL. */
mask_len = strlen (mask);
if(server->unicode_enabled)
mask_size = 1 + 2 * (mask_len+1) + 3;
else
mask_size = 1 + mask_len+1 + 3;
LOG (("SMB call readdir %ld @ %ld\n", cache_size, fpos));
LOG ((" mask = '%s'\n", escape_name(mask)));
@@ -2310,23 +2348,50 @@ smb_proc_readdir_short (struct smb_server *server, const char *path, int fpos, i
{
if (first)
{
ASSERT( smb_payload_size(server, 2, 5 + strlen (mask)) >= 0 );
ASSERT( smb_payload_size(server, 2, mask_size) >= 0 );
p = smb_setup_header (server, SMBsearch, 2, 5 + strlen (mask));
p = smb_setup_header (server, SMBsearch, 2, mask_size);
WSET (buf, smb_vwv0, entries_asked);
WSET (buf, smb_vwv1, SMB_FILE_ATTRIBUTE_DIRECTORY);
p = smb_encode_ascii (p, mask, strlen (mask));
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
p += copy_latin1_to_utf16le(p,2 * (mask_len+1),mask,mask_len);
}
else
{
p = smb_encode_ascii (p, mask, strlen (mask));
}
(*p++) = 5;
(void) smb_encode_word (p, 0);
}
else
{
ASSERT( smb_payload_size(server, 2, 5 + SMB_STATUS_SIZE) >= 0 );
int size;
p = smb_setup_header (server, SMBsearch, 2, 5 + SMB_STATUS_SIZE);
if(server->unicode_enabled)
size = 1 + 2 * (1) + 3 + SMB_STATUS_SIZE;
else
size = 1 + 1 + 3 + SMB_STATUS_SIZE;
ASSERT( smb_payload_size(server, 2, size) >= 0 );
p = smb_setup_header (server, SMBsearch, 2, size);
WSET (buf, smb_vwv0, entries_asked);
WSET (buf, smb_vwv1, SMB_FILE_ATTRIBUTE_DIRECTORY);
p = smb_encode_ascii (p, "", 0);
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
p += copy_latin1_to_utf16le(p,2 * (1),"",0);
}
else
{
p = smb_encode_ascii (p, "", 0);
}
(void) smb_encode_vblock (p, status, SMB_STATUS_SIZE);
}
@@ -3103,15 +3168,30 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
int result;
char *p;
char *buf = server->transmit_buffer;
int path_size;
LOG (("path='%s'\n", escape_name(path)));
ASSERT( smb_payload_size(server, 0, 2 + len) >= 0 );
if(server->unicode_enabled)
path_size = 1 + 2 * (len + 1);
else
path_size = 1 + len + 1;
ASSERT( smb_payload_size(server, 0, path_size) >= 0 );
retry:
p = smb_setup_header (server, SMBgetatr, 0, 2 + len);
smb_encode_ascii (p, path, len);
p = smb_setup_header (server, SMBgetatr, 0, path_size);
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
copy_latin1_to_utf16le(p,2 * (len+1),path,len);
}
else
{
smb_encode_ascii (p, path, len);
}
result = smb_request_ok (server, SMBgetatr, 10, 0, error_ptr);
if (result < 0)
@@ -3473,16 +3553,32 @@ smb_proc_setattr_core (struct smb_server *server, const char *path, int len, con
char *p;
char *buf = server->transmit_buffer;
int result;
int path_size;
ASSERT( smb_payload_size(server, 8, 4 + len) >= 0 );
if(server->unicode_enabled)
path_size = 1 + 2 * (len + 1 + 1);
else
path_size = 1 + len + 1 + 1;
ASSERT( smb_payload_size(server, 8, path_size) >= 0 );
retry:
p = smb_setup_header (server, SMBsetatr, 8, 4 + len);
p = smb_setup_header (server, SMBsetatr, 8, path_size);
WSET (buf, smb_vwv0, new_finfo->attr);
DSET (buf, smb_vwv1, local_time);
p = smb_encode_ascii (p, path, len);
(void) smb_encode_ascii (p, "", 0);
if(server->unicode_enabled)
{
(*p++) = 4; /* A null-terminated string follows. */
p += copy_latin1_to_utf16le(p,2 * (len+1),path,len);
copy_latin1_to_utf16le(p,2 * (1),"",0);
}
else
{
p = smb_encode_ascii (p, path, len);
(void) smb_encode_ascii (p, "", 0);
}
result = smb_request_ok (server, SMBsetatr, 0, 0, error_ptr);
if (result < 0)
@@ -3548,7 +3644,7 @@ smb_proc_dskattr (struct smb_server *server, struct smb_dskattr *attr, int * err
retry:
if (server->protocol >= PROTOCOL_NT1)
if (!server->prefer_core_protocol && server->protocol >= PROTOCOL_NT1)
{
unsigned char *outbuf = server->transmit_buffer;
dword total_allocation_units_low;
+16 -12
View File
@@ -49,6 +49,7 @@ smba_connect (
int timeout,
int opt_raw_smb,
int opt_unicode,
int opt_prefer_core_protocol,
int opt_prefer_write_raw,
int opt_write_behind,
int opt_prefer_read_raw,
@@ -88,6 +89,9 @@ smba_connect (
/* Enable Unicode support if the server supports it, too. */
res->server.use_unicode = opt_unicode;
/* Prefer SMB core protocol commands to NT1 commands, if possible. */
res->server.prefer_core_protocol = opt_prefer_core_protocol;
/* Prefer SMB_COM_WRITE_RAW over SMB_COM_WRITE_ANDX? */
res->server.prefer_write_raw = opt_prefer_write_raw;
@@ -243,7 +247,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
if (!f->is_valid || f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
{
if (f->server->server.protocol >= PROTOCOL_LANMAN2)
if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
result = smb_query_path_information (&s->server, f->dirent.complete_path, f->dirent.len, 0, &f->dirent, error_ptr);
else
result = smb_proc_getattr_core (&s->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
@@ -386,7 +390,7 @@ write_attr (smba_file_t * f, int * error_ptr)
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
if(f->server->server.protocol >= PROTOCOL_LANMAN2)
if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
result = make_open (f, open_need_fid, open_writable, open_dont_truncate, error_ptr);
if (result < 0)
@@ -494,7 +498,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int
D(("read %ld bytes from offset %ld",len,offset));
/* SMB_COM_READ_ANDX supported? */
if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_read_raw)
if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_read_raw && !f->server->server.prefer_core_protocol)
{
QUAD position_quad = (*offset);
int max_readx_size;
@@ -692,7 +696,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
max_buffer_size = f->server->server.max_buffer_size;
/* SMB_COM_WRITE_ANDX supported? */
if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_write_raw)
if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_write_raw && !f->server->server.prefer_core_protocol)
{
QUAD position_quad = (*offset);
int max_writex_size;
@@ -958,7 +962,7 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
{
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
if (f->server->server.protocol >= PROTOCOL_LANMAN2)
if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
if (f->dirent.opened)
result = smb_query_path_information (&f->server->server, NULL, 0, f->dirent.fileid, &f->dirent, error_ptr);
@@ -1060,7 +1064,7 @@ smba_setattr (smba_file_t * f, const smba_stat_t * data, const QUAD * const size
if(result < 0)
goto out;
if(f->server->server.protocol >= PROTOCOL_LANMAN2)
if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
result = smb_set_file_information (&f->server->server, &f->dirent, size, error_ptr);
else
result = smb_proc_trunc (&f->server->server, f->dirent.fileid, size->Low, error_ptr);
@@ -1228,7 +1232,7 @@ smba_create (smba_file_t * dir, const char *name, int * error_ptr)
size_t len;
int result;
result = make_open (dir, open_dont_need_fid, open_writable, open_dont_truncate, error_ptr);
result = make_open (dir, open_dont_need_fid, open_read_only, open_dont_truncate, error_ptr);
if (result < 0)
goto out;
@@ -1251,10 +1255,7 @@ smba_create (smba_file_t * dir, const char *name, int * error_ptr)
path[dir->dirent.len] = DOS_PATHSEP;
memcpy(&path[dir->dirent.len+1], name, len+1); /* Length includes terminating NUL byte. */
/* At least one Samba version crashed when using SMB_COM_NT_CREATE_ANDX
* to create a new file. Let's see if the old way works better.
*/
if (FALSE && dir->server->server.protocol >= PROTOCOL_LANMAN2)
if (!dir->server->server.prefer_core_protocol && dir->server->server.protocol >= PROTOCOL_LANMAN2)
{
int ignored_error;
@@ -1269,6 +1270,7 @@ smba_create (smba_file_t * dir, const char *name, int * error_ptr)
}
else
{
/* Note: smb_proc_create() closes the file just created. */
result = smb_proc_create (&dir->server->server, path, strlen (path), &entry, error_ptr);
if(result < 0)
goto out;
@@ -1292,7 +1294,7 @@ smba_mkdir (smba_file_t * dir, const char *name, int * error_ptr)
int name_len;
int result;
result = make_open (dir, open_dont_need_fid, open_writable, open_dont_truncate, error_ptr);
result = make_open (dir, open_dont_need_fid, open_read_only, open_dont_truncate, error_ptr);
if (result < 0)
goto out;
@@ -1639,6 +1641,7 @@ smba_start(
int opt_timeout,
int opt_raw_smb,
int opt_unicode,
int opt_prefer_core_protocol,
int opt_prefer_write_raw,
int opt_write_behind,
int opt_prefer_read_raw,
@@ -1832,6 +1835,7 @@ smba_start(
opt_timeout,
opt_raw_smb,
opt_unicode,
opt_prefer_core_protocol,
opt_prefer_write_raw,
opt_write_behind,
opt_prefer_read_raw,
+18 -18
View File
@@ -118,25 +118,25 @@ typedef int (*smba_callback_t) (void *callback_data, int fpos, int nextpos, char
/****************************************************************************/
int smba_open(smba_server_t *s, const char *name, int writable, int truncate_file, smba_file_t **file, int * error_ptr);
void smba_close(smba_server_t * s, smba_file_t *f);
int smba_read(smba_file_t *f, char *data, long len, const QUAD * const offset, int * error_ptr);
int smba_write(smba_file_t *f, const char *data, long len, const QUAD * const offset, int * error_ptr);
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 *d, smba_callback_t callback, int * error_ptr);
int smba_create(smba_file_t *dir, const char *name, 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);
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 smb_invalidate_all_inodes(struct smb_server *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_max_transmit, int opt_timeout, int opt_raw_smb, int opt_unicode, int opt_prefer_write_raw, int opt_write_behind, int opt_prefer_read_raw, int * error_ptr, int * smb_error_class_ptr, int * smb_error_ptr, smba_server_t **result);
void smba_disconnect(smba_server_t *server);
int smba_get_dircache_size(struct smba_server * server);
int smba_change_dircache_size(struct smba_server * server,int cache_size);
int smba_open(smba_server_t *s, const char *name, int writable, int truncate_file, smba_file_t **file, int *error_ptr);
void smba_close(smba_server_t *s, smba_file_t *f);
int smba_read(smba_file_t *f, char *data, long len, const QUAD *const offset, int *error_ptr);
int smba_write(smba_file_t *f, const char *data, long len, const QUAD *const offset, int *error_ptr);
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 *error_ptr);
int smba_create(smba_file_t *dir, const char *name, 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);
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 smb_invalidate_all_inodes(struct smb_server *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_max_transmit, int opt_timeout, int opt_raw_smb, int opt_unicode, int opt_prefer_core_protocol, int opt_prefer_write_raw, int opt_write_behind, int opt_prefer_read_raw, int *error_ptr, int *smb_error_class_ptr, int *smb_error_ptr, 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);
/****************************************************************************/
+5 -5
View File
@@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 150
#define DATE "10.6.2018"
#define VERS "smbfs 1.150"
#define VSTRING "smbfs 1.150 (10.6.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.150 (10.6.2018)"
#define REVISION 152
#define DATE "11.6.2018"
#define VERS "smbfs 1.152"
#define VSTRING "smbfs 1.152 (11.6.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.152 (11.6.2018)"
+1 -1
View File
@@ -1 +1 @@
150
152