summaryrefslogtreecommitdiff
path: root/source3/smbd/reply.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r--source3/smbd/reply.c71
1 files changed, 32 insertions, 39 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index a62b54550e..93e2aaf0be 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2733,16 +2733,28 @@ static int setup_readX_header(char *inbuf, char *outbuf, size_t smb_maxcnt)
Reply to a read and X - possibly using sendfile.
****************************************************************************/
-int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
- files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
+static void send_file_readX(connection_struct *conn, struct smb_request *req,
+ files_struct *fsp, SMB_OFF_T startpos,
+ size_t smb_maxcnt)
{
SMB_STRUCT_STAT sbuf;
- int outsize = 0;
ssize_t nread = -1;
- char *data = smb_buf(outbuf);
+ char *data;
+ char *inbuf, *outbuf;
+ int length, len_outbuf;
+
+ if (!reply_prep_legacy(req, &inbuf, &outbuf, &length, &len_outbuf)) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+
+ set_message(inbuf, outbuf, 12, 0, True);
+
+ data = smb_buf(outbuf);
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
+ return;
}
if (startpos > sbuf.st_size) {
@@ -2803,8 +2815,9 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
}
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning -1 here means successful sendfile. */
- return -1;
+ /* No outbuf here means successful sendfile. */
+ TALLOC_FREE(req->outbuf);
+ return;
}
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
@@ -2814,8 +2827,9 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning -1 here means successful sendfile. */
- return -1;
+ /* No outbuf here means successful sendfile. */
+ TALLOC_FREE(req->outbuf);
+ return;
}
#endif
@@ -2836,21 +2850,24 @@ normal_read:
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
- return -1;
+ TALLOC_FREE(req->outbuf);
+ return;
} else {
nread = read_file(fsp,data,startpos,smb_maxcnt);
if (nread < 0) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
+ return;
}
- outsize = setup_readX_header(inbuf, outbuf,nread);
+ setup_readX_header(inbuf, outbuf,nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning the number of bytes we want to send back - including header. */
- return outsize;
+ chain_reply_new(req);
+
+ return;
}
}
@@ -2862,14 +2879,11 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
{
files_struct *fsp;
SMB_OFF_T startpos;
- ssize_t nread = -1;
size_t smb_maxcnt;
BOOL big_readX = False;
#if 0
size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
#endif
- char *inbuf, *outbuf;
- int length, bufsize;
START_PROFILE(SMBreadX);
@@ -2967,28 +2981,7 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
return;
}
- if (!reply_prep_legacy(req, &inbuf, &outbuf, &length, &bufsize)) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBreadX);
- return;
- }
-
- set_message(inbuf,outbuf,12,0,True);
-
- nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp,
- startpos, smb_maxcnt);
- /* Only call chain_reply if not an error. */
- if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) {
- nread = chain_reply(inbuf,&outbuf,length,bufsize);
- }
-
- if (nread == -1) {
- /*
- * Can't use reply_post_legacy here, setup_readX_header has
- * set up its (potentially LARGE) size itself already.
- */
- TALLOC_FREE(req->outbuf);
- }
+ send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
END_PROFILE(SMBreadX);
return;