Updated to version 1.158

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:
Olaf Barthel
2018-06-27 11:14:20 +02:00
parent b6a27b716c
commit bfc6b74ddc
7 changed files with 427 additions and 98 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ int smb_proc_mv(struct smb_server *server, const char *opath, const int olen, co
int smb_proc_mkdir(struct smb_server *server, const char *path, const int len, int * error_ptr);
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, word fid, dword length, 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, int cache_size, struct smb_dirent *entry, 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);
+105 -28
View File
@@ -4836,10 +4836,6 @@ Action_SetProtect(
memset(&st,0,sizeof(st));
st.atime = -1;
st.ctime = -1;
st.mtime = -1;
if((mask & FIBF_DELETE) != 0)
{
SHOWMSG("write/delete protection enabled");
@@ -5378,11 +5374,34 @@ Action_ExamineObject(
SHOWVALUE(fib->fib_DirEntryType);
SHOWVALUE(fib->fib_NumBlocks);
SHOWVALUE(fib->fib_Size);
SHOWVALUE(fib->fib_Date.ds_Days);
SHOWVALUE(fib->fib_Date.ds_Minute);
SHOWVALUE(fib->fib_Date.ds_Tick);
SHOWVALUE(fib->fib_DiskKey);
#if DEBUG
{
struct DateTime dat;
TEXT date[LEN_DATSTRING],time[LEN_DATSTRING];
memset(&dat,0,sizeof(dat));
memset(date,0,sizeof(date));
memset(time,0,sizeof(time));
dat.dat_Stamp = fib->fib_Date;
dat.dat_Format = FORMAT_DEF;
dat.dat_StrDate = date;
dat.dat_StrTime = time;
if(DateToStr(&dat))
{
D(("days=%ld/minutes=%ld/ticks=%ld: %s %s", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick, date, time));
}
else
{
D(("could not convert days=%ld/minutes=%ld/ticks=%ld", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick));
}
}
#endif /* DEBUG */
out:
(*error_ptr) = error;
@@ -5554,6 +5573,32 @@ dir_scan_callback_func_exnext(
fib->fib_Date.ds_Minute = (seconds % (24 * 60 * 60)) / 60;
fib->fib_Date.ds_Tick = (seconds % 60) * TICKS_PER_SECOND;
#if DEBUG
{
struct DateTime dat;
TEXT date[LEN_DATSTRING],time[LEN_DATSTRING];
memset(&dat,0,sizeof(dat));
memset(date,0,sizeof(date));
memset(time,0,sizeof(time));
dat.dat_Stamp = fib->fib_Date;
dat.dat_Format = FORMAT_DEF;
dat.dat_StrDate = date;
dat.dat_StrTime = time;
if(DateToStr(&dat))
{
D((" days=%ld/minutes=%ld/ticks=%ld: %s %s", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick, date, time));
}
else
{
D((" could not convert days=%ld/minutes=%ld/ticks=%ld", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick));
}
}
#endif /* DEBUG */
result = 1;
out:
@@ -5781,9 +5826,16 @@ dir_scan_callback_func_exall(
*/
ed_size = ec->ec_MinSize + name_len+1;
if(ec->ec_Next == NULL || ed_size > ec->ec_BytesLeft)
/* All entries need to begin on a word-aligned address,
* which means that we need to pad the entry size to
* a multiple of 2.
*/
if((ed_size % 2) > 0)
ed_size++;
if(ec->ec_Next == NULL || ec->ec_BytesLeft < ed_size)
{
D(("Not enough room to return this entry: size %ld > ec->ec_BytesLeft %ld",ed_size,ec->ec_BytesLeft));
D(("Not enough room to return this entry: ec->ec_BytesLeft %ld < size %ld",ec->ec_BytesLeft,ed_size));
/* If this is the first directory entry,
* stop the entire process before it has
@@ -5814,7 +5866,7 @@ dir_scan_callback_func_exall(
ed->ed_Next = NULL;
/* Copy the name, including the terminating NUL byte. */
ed->ed_Name = (STRPTR)(((ULONG)ed) + ec->ec_MinSize);
ed->ed_Name = (STRPTR)(&((BYTE *)ed)[ec->ec_MinSize]);
memcpy(ed->ed_Name,name,name_len+1);
/* Fill in as many records as were requested. */
@@ -5908,19 +5960,9 @@ dir_scan_callback_func_exall(
if(ec->ec_Last != NULL)
ec->ec_Last->ed_Next = ed;
/* All entries need to begin on a word-aligned address,
* which means that we need to pad the entry size to
* a multiple of 2.
*/
if((ed_size % 2) > 0)
ed_size++;
/* Note: due to the padding byte the number of bytes
* left may become negative.
*/
ec->ec_BytesLeft -= ed_size;
ec->ec_Next = ec->ec_BytesLeft > 0 ? (struct ExAllData *)(((ULONG)ed) + ed_size) : NULL;
ec->ec_Next = ec->ec_BytesLeft > 0 ? (struct ExAllData *)(&((BYTE *)ed)[ed_size]) : NULL;
ec->ec_Last = ed;
ec->ec_Control->eac_Entries++;
@@ -6138,14 +6180,23 @@ Action_ExamineAll(
#if DEBUG
{
int num_entries_found = 0;
SHOWVALUE(eac->eac_Entries);
while(ed != NULL)
if(eac->eac_Entries > 0)
{
SHOWSTRING(ed->ed_Name);
do
{
SHOWSTRING(ed->ed_Name);
num_entries_found++;
ed = ed->ed_Next;
ed = ed->ed_Next;
}
while(ed != NULL);
}
ASSERT( eac->eac_Entries == num_entries_found );
}
#endif /* DEBUG */
@@ -6817,14 +6868,40 @@ Action_SetDate(
goto out;
}
#if DEBUG
{
struct DateTime dat;
TEXT date[LEN_DATSTRING],time[LEN_DATSTRING];
memset(&dat,0,sizeof(dat));
memset(date,0,sizeof(date));
memset(time,0,sizeof(time));
dat.dat_Stamp = (*ds);
dat.dat_Format = FORMAT_DEF;
dat.dat_StrDate = date;
dat.dat_StrTime = time;
if(DateToStr(&dat))
{
D(("days=%ld/minutes=%ld/ticks=%ld: %s %s", ds->ds_Days, ds->ds_Minute, ds->ds_Tick, date, time));
}
else
{
D(("could not convert days=%ld/minutes=%ld/ticks=%ld", ds->ds_Days, ds->ds_Minute, ds->ds_Tick));
}
}
#endif /* DEBUG */
seconds = (ds->ds_Days * 24 * 60 + ds->ds_Minute) * 60 + (ds->ds_Tick / TICKS_PER_SECOND);
memset(&st,0,sizeof(st));
st.atime = -1;
st.ctime = -1;
st.ctime = 0;
st.atime = 0;
st.mtime = seconds + UNIX_TIME_OFFSET + get_time_zone_delta();
D(("mtime = %lu",st.mtime));
if(smba_setattr(file,&st,NULL,&error) < 0)
{
error = map_errno_to_ioerr(error);
+179 -42
View File
@@ -391,7 +391,7 @@ static size_t strnlen(const char * s,size_t max_size)
if(max_size > 0)
{
while((*s) != '\0' && --max_size > 0)
while((*s) != '\0' && max_size-- > 0)
s++;
}
@@ -1368,10 +1368,16 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
result = smb_request_ok(server, SMBntcreateX, 34, 0, error_ptr);
if (result < 0)
{
int access_error;
SHOWMSG("that didn't work; retrying");
/* Try again in read-only mode? */
if ((*error_ptr) == EACCES || ((*error_ptr) == error_check_smb_error && smb_errno(server->rcls,server->err) == EACCES))
access_error = (*error_ptr);
if(access_error == error_check_smb_error)
access_error = smb_errno(server->rcls,server->err);
if (access_error == EACCES || access_error == EPERM)
{
if(retry_read_only)
{
@@ -1466,8 +1472,16 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
result = smb_request_ok (server, SMBopen, 7, 0, error_ptr);
if (result < 0)
{
int access_error;
SHOWMSG("that didn't work; retrying");
/* Try again in read-only mode? */
if ((*error_ptr) == EACCES || ((*error_ptr) == error_check_smb_error && smb_errno(server->rcls,server->err) == EACCES))
access_error = (*error_ptr);
if(access_error == error_check_smb_error)
access_error = smb_errno(server->rcls,server->err);
if (access_error == EACCES || access_error == EPERM)
{
if(retry_read_only)
{
@@ -1497,10 +1511,10 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
entry->attr = WVAL (buf, smb_vwv1);
/* This is actually just the mtime value, but we use it
/* This is actually just the wtime value, but we use it
* in all other places as well.
*/
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc (DVAL (buf, smb_vwv2));
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc(DVAL (buf, smb_vwv2)); /* Note: this is UTIME, and should be the server's local time. */
#if DEBUG
{
@@ -1546,18 +1560,18 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
* the server
*/
int
smb_proc_close (struct smb_server *server, word fileid, dword mtime, int * error_ptr)
smb_proc_close (struct smb_server *server, word fileid, dword wtime, int * error_ptr)
{
char *buf = server->transmit_buffer;
int result;
/* 0 and 0xffffffff mean: do not set mtime */
if(mtime != 0 && mtime != (dword)0xffffffff)
mtime = utc2local (mtime);
/* Note: wtime is UTIME, and should be the server's local time. */
if(wtime != 0 && wtime != (dword)-1)
wtime = utc2local(wtime);
smb_setup_header (server, SMBclose, 3, 0);
WSET (buf, smb_vwv0, fileid);
DSET (buf, smb_vwv1, mtime);
DSET (buf, smb_vwv1, wtime);
result = smb_request_ok (server, SMBclose, 0, 0, error_ptr);
@@ -2052,16 +2066,18 @@ smb_proc_lockingX (struct smb_server *server, struct smb_dirent *finfo, const st
int
smb_proc_create (struct smb_server *server, const char *path, int len, struct smb_dirent *entry, int * error_ptr)
{
dword local_time = utc2local (entry->ctime);
dword local_time;
int result;
char *p;
char *buf = server->transmit_buffer;
int path_size;
local_time = utc2local(entry->ctime); /* Note: this is UTIME, and should be the server's local time. */
#if DEBUG
{
struct tm tm_utc;
struct tm tm_local;
struct tm tm_utc;
seconds_to_tm(entry->ctime,&tm_utc);
@@ -2368,7 +2384,7 @@ smb_proc_unlink (struct smb_server *server, const char *path, const int len, int
* writes "enough" data to the file.
*/
int
smb_proc_trunc (struct smb_server *server, word fid, dword length, int * error_ptr)
smb_proc_trunc (struct smb_server *server, struct smb_dirent *entry, dword length, int * error_ptr)
{
char *p;
char *buf = server->transmit_buffer;
@@ -2379,7 +2395,7 @@ smb_proc_trunc (struct smb_server *server, word fid, dword length, int * error_p
retry:
p = smb_setup_header (server, SMBwrite, 5, 3);
WSET (buf, smb_vwv0, fid);
WSET (buf, smb_vwv0, entry->fileid);
WSET (buf, smb_vwv1, 0);
DSET (buf, smb_vwv2, length);
WSET (buf, smb_vwv4, 0);
@@ -2390,7 +2406,10 @@ smb_proc_trunc (struct smb_server *server, word fid, dword length, int * error_p
if(result < 0)
{
if ((*error_ptr) != error_check_smb_error && smb_retry (server))
goto retry;
{
if(reopen_entry(server,entry,NULL) == 0)
goto retry;
}
}
else
{
@@ -2826,6 +2845,21 @@ smb_decode_long_dirent (const struct smb_server *server, const char *p, struct s
finfo->len = name_len;
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));
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));
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));
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));
}
#endif /* DEBUG */
}
break;
@@ -2937,6 +2971,21 @@ smb_decode_long_dirent (const struct smb_server *server, const char *p, struct s
finfo->len = name_len;
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));
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));
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));
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));
}
#endif /* DEBUG */
}
break;
@@ -3380,8 +3429,8 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
entry->attr = WVAL (buf, smb_vwv0);
/* The server only tells us just the mtime */
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc (DVAL (buf, smb_vwv1));
/* The server only tells us just the wtime */
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc(DVAL (buf, smb_vwv1)); /* Note: this is UTIME, and should be the server's local time. */
#if DEBUG
{
@@ -3505,7 +3554,19 @@ smb_query_path_information(struct smb_server *server, const char *path, int len,
if (result < 0)
{
if ((*error_ptr) != error_check_smb_error && smb_retry (server))
goto retry;
{
/* We don't need the file id? */
if (len > 0)
{
goto retry;
}
/* We do need the file id. */
else if (reopen_entry(server,entry,NULL) == 0)
{
fid = entry->fileid;
goto retry;
}
}
goto out;
}
@@ -3528,6 +3589,7 @@ smb_query_path_information(struct smb_server *server, const char *path, int len,
entry->atime = convert_long_date_to_time_t(p);
p += 2 * sizeof(dword); /* LastAccessTime */
entry->wtime = convert_long_date_to_time_t(p);
p += 2 * sizeof(dword); /* LastWriteTime */
entry->mtime = convert_long_date_to_time_t(p);
@@ -3577,8 +3639,13 @@ smb_query_path_information(struct smb_server *server, const char *path, int len,
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));
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));
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));
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));
@@ -3704,6 +3771,16 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
DSET(p, 8, 0);
DSET(p, 12, 0);
/* Note that we update both mtime and wtime of the
* directory and not just mtime because some Samba
* versions will end up setting the mtime of the
* directory entry to the time given as the wtime
* value and ignore the mtime value. This happens
* even if the wtime value is given as zero and the
* mtime value is non-zero.
*/
LOG(("entry->mtime = %lu\n",entry->mtime));
convert_time_t_to_long_date(entry->mtime,&change_time_quad);
/* Last write time */
@@ -3758,16 +3835,36 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
int
smb_proc_setattr_core (struct smb_server *server, const char *path, int len, const struct smb_dirent *new_finfo, int * error_ptr)
{
dword local_time = utc2local (new_finfo->mtime);
dword local_time;
char *p;
char *buf = server->transmit_buffer;
int result;
int path_size;
dword attr;
/* Don't do anything if mtime is unset. */
if(new_finfo->mtime == 0 || new_finfo->mtime == (time_t)-1)
return(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 );
/* We cache these because if the connection needs to be
* reestablished, the direntry values will all get
* overwritten.
*/
attr = new_finfo->attr;
local_time = utc2local(new_finfo->mtime); /* Note: this is UTIME, and should be the server's local time. */
#if DEBUG
{
struct tm tm_utc;
struct tm tm_local;
struct tm tm_utc;
seconds_to_tm(new_finfo->mtime,&tm_utc);
@@ -3791,17 +3888,10 @@ smb_proc_setattr_core (struct smb_server *server, const char *path, int len, con
}
#endif /* DEBUG */
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, path_size);
WSET (buf, smb_vwv0, new_finfo->attr);
WSET (buf, smb_vwv0, attr);
DSET (buf, smb_vwv1, local_time);
if(server->unicode_enabled)
@@ -3826,44 +3916,91 @@ smb_proc_setattr_core (struct smb_server *server, const char *path, int len, con
return result;
}
/* smb_proc_setattrE: we do not retry here, because we rely on fid,
* which would not be valid after a retry.
*/
int
smb_proc_setattrE (struct smb_server *server, word fid, struct smb_dirent *new_entry, int * error_ptr)
{
char *buf = server->transmit_buffer;
word date, time_value;
time_t ctime, atime, mtime;
int num_changes;
int result;
/* We cache these because if the connection needs to be
* reestablished, the direntry values will all get
* overwritten.
*/
ctime = new_entry->ctime;
atime = new_entry->atime;
mtime = new_entry->mtime;
retry:
smb_setup_header (server, SMBsetattrE, 7, 0);
WSET (buf, smb_vwv0, fid);
date_unix2dos (new_entry->ctime, &time_value, &date);
num_changes = 0;
if(ctime != 0 && ctime != (time_t)-1)
{
date_unix2dos (ctime, &time_value, &date);
num_changes++;
}
else
{
date = time_value = 0;
}
WSET (buf, smb_vwv1, date);
WSET (buf, smb_vwv2, time_value);
date_unix2dos (new_entry->atime, &time_value, &date);
if(atime != 0 && atime != (time_t)-1)
{
date_unix2dos (atime, &time_value, &date);
num_changes++;
}
else
{
date = time_value = 0;
}
WSET (buf, smb_vwv3, date);
WSET (buf, smb_vwv4, time_value);
date_unix2dos (new_entry->mtime, &time_value, &date);
if(mtime != 0 && mtime != (time_t)-1)
{
date_unix2dos (mtime, &time_value, &date);
num_changes++;
}
else
{
date = time_value = 0;
}
WSET (buf, smb_vwv5, date);
WSET (buf, smb_vwv6, time_value);
result = smb_request_ok (server, SMBsetattrE, 0, 0, error_ptr);
if (result < 0)
/* Do we actually have to change anything at all? */
if(num_changes > 0)
{
if ((*error_ptr) != error_check_smb_error && smb_retry (server))
result = smb_request_ok (server, SMBsetattrE, 0, 0, error_ptr);
if (result < 0)
{
if(reopen_entry(server,new_entry,NULL) == 0)
goto retry;
}
if ((*error_ptr) != error_check_smb_error && smb_retry (server))
{
if(reopen_entry(server,new_entry,NULL) == 0)
{
fid = new_entry->fileid;
goto retry;
}
}
LOG(("that didn't work.\n"));
LOG(("that didn't work.\n"));
}
}
else
{
result = 0;
}
return result;
+85 -21
View File
@@ -423,36 +423,84 @@ write_attr (smba_file_t * f, int * error_ptr)
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
LOG(("mtime = %lu\n",f->dirent.mtime));
if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
/* Copy these, because make_open() may overwrite them. */
time_t mtime = f->dirent.mtime;
dword attr = f->dirent.attr;
LOG(("mtime = %lu\n",f->dirent.mtime));
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));
f->dirent.mtime = mtime;
f->dirent.attr = attr;
result = smb_set_file_information (&f->server->server, &f->dirent, NULL, error_ptr);
if (result < 0)
goto out;
f->attr_dirty = FALSE;
}
else
{
/* Copy these, because make_open() may overwrite them. */
time_t mtime = f->dirent.mtime;
dword attr = f->dirent.attr;
LOG(("mtime = %lu\n",f->dirent.mtime));
result = make_open (f, open_dont_need_fid, open_writable, open_dont_truncate, error_ptr);
if (result < 0)
goto out;
if (f->dirent.opened && f->server->supports_E)
result = smb_proc_setattrE (&f->server->server, f->dirent.fileid, &f->dirent, error_ptr);
else
LOG(("mtime = %lu\n",f->dirent.mtime));
f->dirent.mtime = mtime;
f->dirent.attr = attr;
/* If the attributes need to be updated, we cannot used smb_proc_setattrE(),
* because that only updates the "time of last write access", but not the
* attributes.
*/
if(f->attr_dirty)
{
/* Update the attributes and the "time of last write access". */
result = smb_proc_setattr_core (&f->server->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
}
if(result < 0)
goto out;
if (result < 0)
{
f->attr_time = 0;
goto out;
}
/* Now deal with the creation/access/modification times. */
if (f->dirent.opened && f->server->supports_E)
{
result = smb_proc_setattrE (&f->server->server, f->dirent.fileid, &f->dirent, error_ptr);
if(result < 0)
goto out;
}
f->attr_dirty = FALSE;
f->attr_dirty = FALSE;
}
/* Update the times. */
else
{
if (f->dirent.opened && f->server->supports_E)
result = smb_proc_setattrE (&f->server->server, f->dirent.fileid, &f->dirent, error_ptr);
else
result = smb_proc_setattr_core (&f->server->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
}
}
out:
if (result < 0)
f->attr_time = 0;
return result;
}
@@ -993,6 +1041,8 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
LOG(("using smb_query_path_information\n"));
if (f->dirent.opened)
result = smb_query_path_information (&f->server->server, NULL, 0, f->dirent.fileid, &f->dirent, error_ptr);
else
@@ -1001,9 +1051,17 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
else
{
if (f->dirent.opened && f->server->supports_E)
{
LOG(("using smb_proc_getattrE\n"));
result = smb_proc_getattrE (&f->server->server, &f->dirent, error_ptr);
}
else
{
LOG(("using smb_proc_getattr_core\n"));
result = smb_proc_getattr_core (&f->server->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
}
}
if (result < 0)
@@ -1035,40 +1093,46 @@ 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)
smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size, int * error_ptr)
{
BOOL times_changed = FALSE;
int result = 0;
dword attrs;
if (data != NULL)
if (st != NULL)
{
if (data->atime != (time_t)-1 && f->dirent.atime != data->atime)
if (st->atime != 0 && st->atime != (time_t)-1 && f->dirent.atime != st->atime)
{
f->dirent.atime = data->atime;
LOG(("atime changed to %lu\n",st->atime));
f->dirent.atime = st->atime;
times_changed = TRUE;
}
if (data->ctime != (time_t)-1 && f->dirent.ctime != data->ctime)
if (st->ctime != 0 && st->ctime != (time_t)-1 && f->dirent.ctime != st->ctime)
{
f->dirent.ctime = data->ctime;
LOG(("ctime changed to %lu\n",st->ctime));
f->dirent.ctime = st->ctime;
times_changed = TRUE;
}
if (data->mtime != (time_t)-1 && f->dirent.mtime != data->mtime)
if (st->mtime != 0 && st->mtime != (time_t)-1 && f->dirent.mtime != st->mtime)
{
f->dirent.mtime = data->mtime;
LOG(("mtime changed to %lu\n",st->mtime));
f->dirent.mtime = st->mtime;
times_changed = TRUE;
}
attrs = f->dirent.attr;
if (data->is_read_only)
if (st->is_read_only)
attrs |= SMB_FILE_ATTRIBUTE_READONLY;
else
attrs &= ~SMB_FILE_ATTRIBUTE_READONLY;
if (data->is_changed_since_last_archive)
if (st->is_changed_since_last_archive)
attrs |= SMB_FILE_ATTRIBUTE_ARCHIVE;
else
attrs &= ~SMB_FILE_ATTRIBUTE_ARCHIVE;
@@ -1096,7 +1160,7 @@ smba_setattr (smba_file_t * f, const smba_stat_t * data, const QUAD * const size
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);
result = smb_proc_trunc (&f->server->server, &f->dirent, size->Low, error_ptr);
if(result < 0)
goto out;
+5 -5
View File
@@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 155
#define DATE "24.6.2018"
#define VERS "smbfs 1.155"
#define VSTRING "smbfs 1.155 (24.6.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.155 (24.6.2018)"
#define REVISION 158
#define DATE "27.6.2018"
#define VERS "smbfs 1.158"
#define VSTRING "smbfs 1.158 (27.6.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.158 (27.6.2018)"
+1 -1
View File
@@ -1 +1 @@
155
158