1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-13 16:23:50 +03:00

Fixed allocation bug in database prog. Some format fixes.

Jeremy.
This commit is contained in:
Jeremy Allison
-
parent 8bb5cb27c2
commit 9ff6b0c20c
4 changed files with 1037 additions and 1049 deletions

View File

@@ -189,4 +189,7 @@
/* the maximum age in seconds of a password. Should be a lp_ parameter */
#define MAX_PASSWORD_AGE (21*24*60*60)
/* Allocation roundup. */
#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000
#endif

View File

@@ -159,6 +159,7 @@
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
#define SMB_ROUNDUP_ALLOCATION(s) (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE)))
/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)

View File

@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB transaction2 handling
Copyright (C) Jeremy Allison 1994-1998
Copyright (C) Jeremy Allison 1994-2001
Extensively modified by Andrew Tridgell, 1995
@@ -37,6 +37,7 @@ extern pstring global_myname;
set correctly for the type of call.
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
static int send_trans2_replies(char *outbuf, int bufsize, char *params,
int paramsize, char *pdata, int datasize)
{
@@ -181,10 +182,10 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
return 0;
}
/****************************************************************************
reply to a TRANSACT2_OPEN
Reply to a TRANSACT2_OPEN.
****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
int bufsize,
char **pparams, char **ppdata)
@@ -289,21 +290,25 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
}
/*********************************************************
* Routine to check if a given string matches exactly.
* as a special case a mask of "." does NOT match. That
* is required for correct wildcard semantics
* Case can be significant or not.
Routine to check if a given string matches exactly.
as a special case a mask of "." does NOT match. That
is required for correct wildcard semantics
Case can be significant or not.
**********************************************************/
static BOOL exact_match(char *str,char *mask, BOOL case_sig)
{
if (mask[0] == '.' && mask[1] == 0) return False;
if (case_sig) return strcmp(str,mask)==0;
if (mask[0] == '.' && mask[1] == 0)
return False;
if (case_sig)
return strcmp(str,mask)==0;
return strcasecmp(str,mask) == 0;
}
/****************************************************************************
get a level dependent lanman2 dir entry.
Get a level dependent lanman2 dir entry.
****************************************************************************/
static BOOL get_lanman2_dir_entry(connection_struct *conn,
void *inbuf, void *outbuf,
char *path_mask,int dirtype,int info_level,
@@ -324,6 +329,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
int prev_dirpos=0;
int mode=0;
SMB_OFF_T size = 0;
SMB_OFF_T allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
char *nameptr;
@@ -339,18 +345,15 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
return(False);
p = strrchr_m(path_mask,'/');
if(p != NULL)
{
if(p != NULL) {
if(p[1] == '\0')
pstrcpy(mask,"*.*");
else
pstrcpy(mask, p+1);
}
else
} else
pstrcpy(mask, path_mask);
while (!found)
{
while (!found) {
BOOL got_match;
/* Needed if we run out of space */
@@ -374,9 +377,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(fname,dname);
if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
got_match = mask_match(fname, mask, case_sensitive);
}
if(!got_match && !is_8_3(fname, False)) {
@@ -394,8 +396,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
got_match = mask_match(newname, mask, case_sensitive);
}
if(got_match)
{
if(got_match) {
BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
if (dont_descend && !isdots)
continue;
@@ -404,19 +405,17 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
if(needslash)
pstrcat(pathreal,"/");
pstrcat(pathreal,dname);
if (vfs_stat(conn,pathreal,&sbuf) != 0)
{
if (vfs_stat(conn,pathreal,&sbuf) != 0) {
/* Needed to show the msdfs symlinks as directories */
if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
|| !is_msdfs_link(conn, pathreal))
{
|| !is_msdfs_link(conn, pathreal)) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
pathreal,strerror(errno)));
continue;
}
else
{
DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
} else {
DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n",
pathreal));
sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
}
}
@@ -429,6 +428,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
size = sbuf.st_size;
allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@@ -455,8 +455,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
switch (info_level)
{
switch (info_level) {
case 1:
if(requires_resume_key) {
SIVAL(p,0,reskey);
@@ -466,7 +465,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l1_fdateLastAccess,adate);
put_dos_date2(p,l1_fdateLastWrite,mdate);
SIVAL(p,l1_cbFile,(uint32)size);
SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l1_attrFile,mode);
p += l1_achName;
nameptr = p;
@@ -477,7 +476,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
break;
case 2:
/* info_level 2 */
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
@@ -486,13 +484,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_dos_date2(p,l2_fdateLastAccess,adate);
put_dos_date2(p,l2_fdateLastWrite,mdate);
SIVAL(p,l2_cbFile,(uint32)size);
SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
SSVAL(p,l2_attrFile,mode);
SIVAL(p,l2_cbList,0); /* No extended attributes */
p += l2_achName;
nameptr = p;
len = srvstr_push(outbuf, p, fname, -1,
STR_NOALIGN);
len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
SCVAL(p, -1, len);
p += len;
*p++ = 0; /* craig from unisys pointed out we need this */
@@ -507,7 +504,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size);
SOFF_T(p,8,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
q = p; p += 4;
@@ -541,7 +538,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size);
SOFF_T(p,8,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
p += 4;
@@ -554,7 +551,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p = pdata + len;
break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
p += 4;
SIVAL(p,0,reskey); p += 4;
@@ -563,7 +559,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
put_long_date(p,mdate); p += 8;
put_long_date(p,mdate); p += 8;
SOFF_T(p,0,size);
SOFF_T(p,8,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
p += 4;
@@ -613,7 +609,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
return(found);
}
/****************************************************************************
Reply to a TRANS2_FINDFIRST.
****************************************************************************/
@@ -839,10 +834,10 @@ static int call_trans2findfirst(connection_struct *conn,
return(-1);
}
/****************************************************************************
reply to a TRANS2_FINDNEXT
Reply to a TRANS2_FINDNEXT.
****************************************************************************/
static int call_trans2findnext(connection_struct *conn,
char *inbuf, char *outbuf,
int length, int bufsize,
@@ -1092,7 +1087,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
}
/****************************************************************************
reply to a TRANS2_QFSINFO (query filesystem info)
Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
static int call_trans2qfsinfo(connection_struct *conn,
@@ -1225,8 +1220,9 @@ static int call_trans2qfsinfo(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_SETFSINFO (set filesystem info)
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
static int call_trans2setfsinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
@@ -1263,6 +1259,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 info_level;
int mode=0;
SMB_OFF_T size=0;
SMB_OFF_T allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
pstring fname;
@@ -1307,8 +1304,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pstrcpy(fname, fsp->fsp_name);
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",
fsp->fnum, strerror(errno)));
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
@@ -1320,8 +1316,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/* qpathinfo */
info_level = SVAL(params,0);
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
info_level));
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE);
@@ -1344,27 +1339,27 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
fname,info_level,tran_call,total_data));
p = strrchr_m(fname,'/');
if (!p) {
if (!p)
base_name = fname;
} else {
else
base_name = p+1;
}
mode = dos_mode(conn,fname,&sbuf);
size = sbuf.st_size;
if (mode & aDIR) size = 0;
allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
if (mode & aDIR)
size = 0;
params = Realloc(*pparams,2);
if (params == NULL) {
if (params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
}
*pparams = params;
memset((char *)params,'\0',2);
data_size = max_data_bytes + 1024;
pdata = Realloc(*ppdata, data_size);
if ( pdata == NULL ) {
if ( pdata == NULL )
return ERROR_DOS(ERRDOS,ERRnomem);
}
*ppdata = pdata;
if (total_data > 0 && IVAL(pdata,0) == total_data) {
@@ -1384,8 +1379,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
sbuf.st_mtime &= ~1;
}
switch (info_level)
{
switch (info_level) {
case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE:
data_size = (info_level==1?22:26);
@@ -1393,7 +1387,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
SIVAL(pdata,l1_cbFile,(uint32)size);
SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
break;
@@ -1404,7 +1398,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,4,sbuf.st_atime);
put_dos_date2(pdata,8,sbuf.st_mtime);
SIVAL(pdata,12,(uint32)size);
SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode);
break;
@@ -1447,7 +1441,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_STANDARD_INFO:
data_size = 24;
/* Fake up allocation size. */
SOFF_T(pdata,0,SMB_ROUNDUP(size + 1, ((SMB_OFF_T)0x100000)));
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
CVAL(pdata,20) = 0;
@@ -1466,17 +1460,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pstrcpy(short_name,base_name);
/* Mangle if not already 8.3 */
if(!is_8_3(short_name, True))
{
if(!is_8_3(short_name, True)) {
if(!name_map_mangle(short_name,True,True,SNUM(conn)))
*short_name = '\0';
}
len = srvstr_push(outbuf, pdata+4, short_name, -1,
STR_TERMINATE|STR_UPPER);
len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
data_size = 4 + len;
SIVAL(pdata,0,len);
}
break;
}
case SMB_QUERY_FILE_NAME_INFO:
/*
@@ -1494,14 +1486,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,0,len);
break;
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
case SMB_QUERY_FILE_END_OF_FILEINFO:
data_size = 8;
SOFF_T(pdata,0,size);
break;
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
data_size = 8;
SOFF_T(pdata,0,allocation_size);
break;
case SMB_QUERY_FILE_ALL_INFO:
put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime);
@@ -1509,7 +1505,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,mode);
pdata += 40;
SOFF_T(pdata,0,size);
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
CVAL(pdata,20) = delete_pending;
@@ -1622,7 +1618,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,0,0); /* ??? */
SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
SOFF_T(pdata,8,size);
SIVAL(pdata,16,0x20); /* ??? */
SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
}
@@ -1640,8 +1636,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,0x20); /* ??? */
SIVAL(pdata,36,0); /* ??? */
SIVAL(pdata,32,allocation_size);
SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
@@ -1654,17 +1649,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
data_size = 8;
break;
/*
* End new completely undocumented info levels... JRA.
*/
#if 0
/* NT4 server just returns "invalid query" to this - if we try to answer
it then NTws gets a BSOD! (tridge) */
case SMB_QUERY_FILE_STREAM_INFO:
SIVAL(pdata,0,pos);
SIVAL(pdata,4,size);
SIVAL(pdata,12,size);
SIVAL(pdata,4,(uint32)size);
SIVAL(pdata,12,(uint32)allocation_size);
len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
SIVAL(pdata,20,len);
data_size = 24 + len;
@@ -1681,8 +1672,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_SETFILEINFO (set file info by fileid)
Reply to a TRANS2_SETFILEINFO (set file info by fileid).
****************************************************************************/
static int call_trans2setfilepathinfo(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize, char **pparams,
@@ -1715,8 +1707,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
unix_convert(fname,conn,0,&bad_path,&sbuf);
if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
@@ -1729,8 +1720,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
fsp->share_mode = FILE_DELETE_ON_CLOSE;
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
fsp->fsp_name ));
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
@@ -1755,10 +1745,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
info_level = SVAL(params,0);
srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE);
unix_convert(fname,conn,0,&bad_path,&sbuf);
if(!check_name(fname, conn))
{
if((errno == ENOENT) && bad_path)
{
if(!check_name(fname, conn)) {
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
@@ -1767,8 +1755,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if(!VALID_STAT(sbuf)) {
DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
if((errno == ENOENT) && bad_path)
{
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
@@ -1784,9 +1771,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* Realloc the parameter and data sizes */
params = Realloc(*pparams,2);
if(params == NULL) {
if(params == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
}
*pparams = params;
SSVAL(params,0,0);
@@ -1802,8 +1788,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
return ERROR_DOS(ERRDOS,ERReasnotsupported);
}
switch (info_level)
{
switch (info_level) {
case SMB_INFO_STANDARD:
case SMB_INFO_QUERY_EA_SIZE:
{
@@ -1856,33 +1841,32 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* Prefer a defined time to an undefined one. */
if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
? changed_time
: write_time);
? changed_time : write_time);
/* attributes */
mode = IVAL(pdata,32);
break;
}
case 1019:
case 1020:
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_SET_FILE_ALLOCATION_INFO:
{
int ret = -1;
size = IVAL(pdata,0);
SMB_OFF_T allocation_size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return ERROR_DOS(ERRDOS,ERRunknownlevel);
#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
fname, (double)size ));
fname, (double)allocation_size ));
if(size != sbuf.st_size) {
if(allocation_size != sbuf.st_size) {
SMB_STRUCT_STAT new_sbuf;
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
fname, (double)size ));
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
fname, (double)allocation_size ));
if (fd == -1) {
files_struct *new_fsp = NULL;
@@ -1906,14 +1890,24 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (new_fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadpath));
ret = vfs_allocate_file_space(new_fsp, size);
ret = vfs_allocate_file_space(new_fsp, allocation_size);
if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
ret = -1;
}
close_file(new_fsp,True);
} else {
ret = vfs_allocate_file_space(fsp, size);
if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
ret = -1;
}
if (ret == -1) return ERROR_NT(NT_STATUS_DISK_FULL);
}
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
sbuf.st_size = size;
/* Allocate can trucate size... */
size = new_sbuf.st_size;
}
break;
@@ -2020,10 +2014,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
}
default:
{
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
}
/* get some defaults (no modifications) if any info is zero or -1. */
if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
@@ -2041,6 +2033,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
(info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
(info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
(info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
/*
* Only do this test if we are not explicitly
* changing the size of a file.
@@ -2049,8 +2042,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
size = sbuf.st_size;
}
/* Try and set the times, size and mode of this file -
if they are different from the current values
/*
* Try and set the times, size and mode of this file -
* if they are different from the current values
*/
if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
if(fsp != NULL) {
@@ -2063,8 +2057,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
*/
if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
ctime(&tvs.modtime) ));
DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
fsp->pending_modtime = tvs.modtime;
}
@@ -2080,8 +2073,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
/* check the mode isn't different, before changing it */
if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
fname, mode ));
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
if(file_chmod(conn, fname, mode, NULL)) {
DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
@@ -2131,8 +2123,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_MKDIR (make directory with extended attributes).
Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/
static int call_trans2mkdir(connection_struct *conn,
char *inbuf, char *outbuf, int length, int bufsize,
char **pparams, char **ppdata)
@@ -2180,9 +2173,10 @@ static int call_trans2mkdir(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
We don't actually do this - we just send a null response.
****************************************************************************/
static int call_trans2findnotifyfirst(connection_struct *conn,
char *inbuf, char *outbuf,
int length, int bufsize,
@@ -2225,9 +2219,10 @@ static int call_trans2findnotifyfirst(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
changes). Currently this does nothing.
****************************************************************************/
static int call_trans2findnotifynext(connection_struct *conn,
char *inbuf, char *outbuf,
int length, int bufsize,
@@ -2253,8 +2248,9 @@ static int call_trans2findnotifynext(connection_struct *conn,
}
/****************************************************************************
reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/
static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
char* outbuf, int length, int bufsize,
char** pparams, char** ppdata)
@@ -2285,7 +2281,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
#define LMFUNC_GETJOBID 0x60
/****************************************************************************
reply to a TRANS2_IOCTL - used for OS/2 printing.
Reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/
static int call_trans2ioctl(connection_struct *conn, char* inbuf,
@@ -2318,8 +2314,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
}
/****************************************************************************
reply to a SMBfindclose (stop trans2 directory search)
Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
int reply_findclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -2340,8 +2337,9 @@ int reply_findclose(connection_struct *conn,
}
/****************************************************************************
reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
int reply_findnclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -2365,10 +2363,10 @@ int reply_findnclose(connection_struct *conn,
return(outsize);
}
/****************************************************************************
reply to a SMBtranss2 - just ignore it!
Reply to a SMBtranss2 - just ignore it!
****************************************************************************/
int reply_transs2(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -2379,8 +2377,9 @@ int reply_transs2(connection_struct *conn,
}
/****************************************************************************
reply to a SMBtrans2
Reply to a SMBtrans2.
****************************************************************************/
int reply_trans2(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{

View File

@@ -283,12 +283,13 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
size_t total=0;
ssize_t ret;
while (total < N)
{
while (total < N) {
ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
if (ret == -1) return -1;
if (ret == 0) return total;
if (ret == -1)
return -1;
if (ret == 0)
return total;
total += ret;
}
@@ -305,10 +306,15 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
{
int ret;
SMB_STRUCT_STAT st;
struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
connection_struct *conn = fsp->conn;
struct vfs_ops *vfs_ops = &conn->vfs_ops;
SMB_OFF_T space_avail;
SMB_BIG_UINT bsize,dfree,dsize;
#if 0
if (!lp_strict_allocate(SNUM(fsp->conn)))
return vfs_set_filelen(fsp, len);
#endif
release_level_2_oplocks_on_change(fsp);
@@ -337,41 +343,20 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
return ret;
}
/* Grow - we need to write out the space.... */
{
static unsigned char zero_space[65536];
/* Grow - we need to test if we have enough space. */
SMB_OFF_T start_pos = st.st_size;
SMB_OFF_T len_to_write = len - st.st_size;
SMB_OFF_T retlen;
len -= st.st_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
space_avail = (SMB_OFF_T)conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f\n",
fsp->fsp_name, (double)st.st_size ));
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %lu, space avail = %lu\n",
fsp->fsp_name, (double)st.st_size, (unsigned long)len, (unsigned long)space_avail ));
if ((retlen = vfs_ops->lseek(fsp, fsp->fd, start_pos, SEEK_SET)) != start_pos)
return -1;
while ( len_to_write > 0) {
SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),len_to_write);
retlen = vfs_ops->write(fsp,fsp->fd,(const char *)zero_space,current_len_to_write);
if (retlen <= 0) {
/* Write fail - return to original size. */
int save_errno = errno;
fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, st.st_size);
errno = save_errno;
DEBUG(10,("vfs_allocate_file_space: file %s, grow. write fail %s\n",
fsp->fsp_name, strerror(errno) ));
if (len > space_avail) {
errno = ENOSPC;
return -1;
}
DEBUG(10,("vfs_allocate_file_space: file %s, grow. wrote %.0f\n",
fsp->fsp_name, (double)retlen ));
len_to_write -= retlen;
}
set_filelen_write_cache(fsp, len);
}
return 0;
}