1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-14 20:23:54 +03:00

Use a logical cli_read(), removed the cli_read_one() hack.

Jeremy.
This commit is contained in:
Jeremy Allison
-
parent 5a5d33b946
commit 2999eab5ab
2 changed files with 64 additions and 127 deletions

View File

@@ -26,7 +26,8 @@
/**************************************************************************** /****************************************************************************
issue a single SMBread and don't wait for a reply issue a single SMBread and don't wait for a reply
****************************************************************************/ ****************************************************************************/
static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
size_t size, int i) size_t size, int i)
{ {
memset(cli->outbuf,'\0',smb_size); memset(cli->outbuf,'\0',smb_size);
@@ -45,148 +46,89 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_vwv6,size);
SSVAL(cli->outbuf,smb_mid,cli->mid + i); SSVAL(cli->outbuf,smb_mid,cli->mid + i);
cli_send_smb(cli); return cli_send_smb(cli);
} }
/**************************************************************************** /****************************************************************************
issue a single SMBread and wait for a reply. This function only called Read size bytes at offset offset using SMBreadX.
in the rpc pipe code to read dce/rpc reply fragments.
****************************************************************************/ ****************************************************************************/
size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset,
size_t size) ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
{ {
uint32 ecode; uint32 ecode;
uint8 eclass; uint8 eclass;
char *p; char *p;
int size2; int size2;
int readsize;
ssize_t total = 0;
if (size == 0) if (size == 0)
return 0; return 0;
/* Issue a read and receive a reply */ /*
* Set readsize to the maximum size we can handle in one readX,
* rounded down to a multiple of 1024.
*/
cli_issue_read(cli, fnum, offset, size, 0); readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
if (readsize > size )
readsize = size;
if (!cli_receive_smb(cli)) while (total < size) {
return -1;
size2 = SVAL(cli->inbuf, smb_vwv5); /* Issue a read and receive a reply */
/* Check for error. Because the client library doesn't support if (!cli_issue_read(cli, fnum, offset, readsize, 0))
STATUS32, we need to check for and ignore the more data error return -1;
for pipe support. */
if (cli_error(cli, &eclass, &ecode, NULL) && if (!cli_receive_smb(cli))
(eclass != ERRDOS && ecode != ERRmoredata)) { return -1;
return -1;
}
if (size2 > size) { /*
DEBUG(5,("server returned more than we wanted!\n")); * Check for error. Because the client library doesn't support
return -1; * STATUS32, we need to check for and ignore the more data error
} * for pipe support.
*/
/* Copy data into buffer */ if (cli_error(cli, &eclass, &ecode, NULL) &&
(eclass != ERRDOS && ecode != ERRmoredata)) {
p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); return -1;
memcpy(buf, p, size2);
return size2;
}
/****************************************************************************
read from a file
****************************************************************************/
size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
{
char *p;
int total = -1;
/*
* There is a problem in this code when mpx is more than one.
* for some reason files can get corrupted when being read.
* Until we understand this fully I am serializing reads (one
* read/one reply) for now. JRA.
*/
#if 0
int mpx = MAX(cli->max_mux-1, 1);
#else
int mpx = 1;
#endif
int block;
int mid;
int blocks;
/* issued is the number of readX requests we have sent so far */
int issued=0;
/* received is the number of readX replies we have received */
int received=0;
/* maybe its a very silly request? */
if (size == 0) return 0;
/* set block to the maximum size we can handle in one readX,
rounded down to a multiple of 1024 */
block = (cli->max_xmit - (smb_size+32)) & ~1023;
/* work out how many readX calls we will need in total */
blocks = (size + (block-1)) / block;
while (received < blocks) {
int size2;
while (issued - received < mpx && issued < blocks) {
int size1 = MIN(block, size-issued*block);
cli_issue_read(cli, fnum, offset+issued*block, size1, issued);
issued++;
} }
if (!cli_receive_smb(cli)) {
return total;
}
received++;
mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
size2 = SVAL(cli->inbuf, smb_vwv5); size2 = SVAL(cli->inbuf, smb_vwv5);
if (CVAL(cli->inbuf,smb_rcls) != 0) { if (size2 > readsize) {
blocks = MIN(blocks, mid-1); DEBUG(5,("server returned more than we wanted!\n"));
continue; return -1;
} } else if (size2 < 0) {
DEBUG(5,("read return < 0!\n"));
if (size2 <= 0) {
blocks = MIN(blocks, mid-1);
/* this distinguishes EOF from an error */
total = MAX(total, 0);
continue;
}
if (size2 > block) {
DEBUG(0,("server returned more than we wanted!\n"));
return -1;
}
if (mid >= issued) {
DEBUG(0,("invalid mid from server!\n"));
return -1; return -1;
} }
/* Copy data into buffer */
p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6);
memcpy(buf + total, p, size2);
memcpy(buf+mid*block, p, size2); total += size2;
offset += size2;
total = MAX(total, mid*block + size2); /*
* If the server returned less than we asked for we're at EOF.
*/
if (size2 < readsize)
break;
} }
while (received < issued) {
cli_receive_smb(cli);
received++;
}
return total; return total;
} }
/**************************************************************************** /****************************************************************************
issue a single SMBwrite and don't wait for a reply issue a single SMBwrite and don't wait for a reply
****************************************************************************/ ****************************************************************************/
static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf,
static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf,
size_t size, int i) size_t size, int i)
{ {
char *p; char *p;
@@ -223,7 +165,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
SSVAL(cli->outbuf,smb_mid,cli->mid + i); SSVAL(cli->outbuf,smb_mid,cli->mid + i);
show_msg(cli->outbuf); show_msg(cli->outbuf);
cli_send_smb(cli); return cli_send_smb(cli);
} }
/**************************************************************************** /****************************************************************************
@@ -233,6 +175,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
0x0004 use raw named pipe protocol 0x0004 use raw named pipe protocol
0x0008 start of message mode named pipe protocol 0x0008 start of message mode named pipe protocol
****************************************************************************/ ****************************************************************************/
ssize_t cli_write(struct cli_state *cli, ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode, int fnum, uint16 write_mode,
char *buf, off_t offset, size_t size) char *buf, off_t offset, size_t size)
@@ -246,45 +189,39 @@ ssize_t cli_write(struct cli_state *cli,
while (received < blocks) { while (received < blocks) {
while ((issued - received < mpx) && (issued < blocks)) while ((issued - received < mpx) && (issued < blocks)) {
{
int bsent = issued * block; int bsent = issued * block;
int size1 = MIN(block, size - bsent); int size1 = MIN(block, size - bsent);
cli_issue_write(cli, fnum, offset + bsent, if (!cli_issue_write(cli, fnum, offset + bsent,
write_mode, write_mode,
buf + bsent, buf + bsent,
size1, issued); size1, issued))
return -1;
issued++; issued++;
} }
if (!cli_receive_smb(cli)) if (!cli_receive_smb(cli))
{
return bwritten; return bwritten;
}
received++; received++;
if (CVAL(cli->inbuf,smb_rcls) != 0) if (CVAL(cli->inbuf,smb_rcls) != 0)
{
break; break;
}
bwritten += SVAL(cli->inbuf, smb_vwv2); bwritten += SVAL(cli->inbuf, smb_vwv2);
} }
while (received < issued && cli_receive_smb(cli)) while (received < issued && cli_receive_smb(cli))
{
received++; received++;
}
return bwritten; return bwritten;
} }
/**************************************************************************** /****************************************************************************
write to a file using a SMBwrite and not bypassing 0 byte writes write to a file using a SMBwrite and not bypassing 0 byte writes
****************************************************************************/ ****************************************************************************/
ssize_t cli_smbwrite(struct cli_state *cli, ssize_t cli_smbwrite(struct cli_state *cli,
int fnum, char *buf, off_t offset, size_t size1) int fnum, char *buf, off_t offset, size_t size1)
{ {
@@ -315,17 +252,18 @@ ssize_t cli_smbwrite(struct cli_state *cli,
cli_setup_bcc(cli, p); cli_setup_bcc(cli, p);
cli_send_smb(cli); if (!cli_send_smb(cli))
if (!cli_receive_smb(cli)) { return -1;
if (!cli_receive_smb(cli))
return -1; return -1;
}
if (CVAL(cli->inbuf,smb_rcls) != 0) { if (CVAL(cli->inbuf,smb_rcls) != 0)
return -1; return -1;
}
size = SVAL(cli->inbuf,smb_vwv0); size = SVAL(cli->inbuf,smb_vwv0);
if (size == 0) break; if (size == 0)
break;
size1 -= size; size1 -= size;
total += size; total += size;
@@ -333,4 +271,3 @@ ssize_t cli_smbwrite(struct cli_state *cli,
return total; return total;
} }

View File

@@ -76,7 +76,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re
if (size > (size_t)data_to_read) if (size > (size_t)data_to_read)
size = (size_t)data_to_read; size = (size_t)data_to_read;
num_read = (int)cli_read_one(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size);
DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
num_read, stream_offset, data_to_read)); num_read, stream_offset, data_to_read));
@@ -467,7 +467,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr
prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL);
prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
num_read = cli_read_one(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
if (cli_error(cli, &eclass, &ecode, NULL) && if (cli_error(cli, &eclass, &ecode, NULL) &&
(eclass != ERRDOS && ecode != ERRmoredata)) { (eclass != ERRDOS && ecode != ERRmoredata)) {
DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n",