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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, ¶ms[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, ¶ms[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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user