NamedPipe DCE/RPC struct split
Luke Kenneth Casson Leighton
lkcl at samba-tng.org
Tue Jan 15 03:17:12 GMT 2002
hiya, second version.
p->p removed. p->p->vuid removed. p->p->conn removed.
unrelated cleanups of original code not included.
andrew the cleanups do you think that should be done _before_
or after?
attached also is a patch to split out a select() on
a socket into a function "read_data_outstanding()",
from read_with_timeout(). read_with_timeout() updated
accordingly to use function from whence it was derived,
a la cut/paste (actually mx25hd'x50jp or thereabouts :).
lkcl
-------------- next part --------------
Index: include/ntdomain.h
===================================================================
RCS file: /cvsroot/samba/source/include/ntdomain.h,v
retrieving revision 1.73
diff -u -u -r1.73 ntdomain.h
--- include/ntdomain.h 14 Sep 2001 04:31:15 -0000 1.73
+++ include/ntdomain.h 15 Jan 2002 11:00:40 -0000
@@ -159,15 +159,19 @@
fstring mach_acct; /* Machine name we've authenticated. */
};
+/*
+ * DCE/RPC-specific samba-internal-specific handling of data on
+ * NamedPipes.
+ *
+ */
+
typedef struct pipes_struct
{
struct pipes_struct *next, *prev;
- int pnum;
+
connection_struct *conn;
uint16 vuid; /* points to the unauthenticated user that opened this pipe. */
- BOOL open; /* open connection */
- uint16 device_state;
- uint16 priority;
+
fstring name;
fstring pipe_srv_name;
@@ -226,10 +230,6 @@
output_data out_data;
- /* When replying to an SMBtrans, this is the maximum amount of
- data that can be sent in the initial reply. */
- int max_trans_reply;
-
/* talloc context to use when allocating memory on this pipe. */
TALLOC_CTX *mem_ctx;
@@ -237,6 +237,30 @@
struct handle_list *pipe_handles;
} pipes_struct;
+
+typedef struct smb_np_struct
+{
+ struct smb_np_struct *next, *prev;
+ int pnum;
+ connection_struct *conn;
+ uint16 vuid; /* points to the unauthenticated user that opened this pipe. */
+ BOOL open; /* open connection */
+ uint16 device_state;
+ uint16 priority;
+ fstring name;
+
+ /* When replying to an SMBtrans, this is the maximum amount of
+ data that can be sent in the initial reply. */
+ int max_trans_reply;
+
+ /*
+ * NamedPipe state information.
+ *
+ * (e.g. typecast a np_struct, above).
+ */
+ void *np_state;
+
+} smb_np_struct;
struct api_struct
{
Index: rpc_server/srv_lsa_hnd.c
===================================================================
RCS file: /cvsroot/samba/source/rpc_server/srv_lsa_hnd.c,v
retrieving revision 1.31
diff -u -u -r1.31 srv_lsa_hnd.c
--- rpc_server/srv_lsa_hnd.c 2 Oct 2001 04:29:40 -0000 1.31
+++ rpc_server/srv_lsa_hnd.c 15 Jan 2002 11:00:44 -0000
@@ -35,10 +35,10 @@
BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
{
- pipes_struct *plist = get_first_pipe();
+ pipes_struct *plist = get_first_internal_pipe();
struct handle_list *hl = NULL;
- for (plist = get_first_pipe(); plist; plist = get_next_pipe(plist)) {
+ for (plist = get_first_internal_pipe(); plist; plist = get_next_internal_pipe(plist)) {
if (strequal( plist->name, pipe_name)) {
if (!plist->pipe_handles) {
pstring msg;
Index: rpc_server/srv_pipe_hnd.c
===================================================================
RCS file: /cvsroot/samba/source/rpc_server/srv_pipe_hnd.c,v
retrieving revision 1.72
diff -u -u -r1.72 srv_pipe_hnd.c
--- rpc_server/srv_pipe_hnd.c 5 Nov 2001 07:42:55 -0000 1.72
+++ rpc_server/srv_pipe_hnd.c 15 Jan 2002 11:00:46 -0000
@@ -26,26 +26,41 @@
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
-static pipes_struct *chain_p;
+static smb_np_struct *chain_p;
static int pipes_open;
#ifndef MAX_OPEN_PIPES
#define MAX_OPEN_PIPES 2048
#endif
-static pipes_struct *Pipes;
+static smb_np_struct *Pipes;
+static pipes_struct *InternalPipes;
static struct bitmap *bmap;
/****************************************************************************
Pipe iterator functions.
****************************************************************************/
-pipes_struct *get_first_pipe(void)
+smb_np_struct *get_first_pipe(void)
{
return Pipes;
}
-pipes_struct *get_next_pipe(pipes_struct *p)
+smb_np_struct *get_next_pipe(smb_np_struct *p)
+{
+ return p->next;
+}
+
+/****************************************************************************
+ Internal Pipe iterator functions.
+****************************************************************************/
+
+pipes_struct *get_first_internal_pipe(void)
+{
+ return InternalPipes;
+}
+
+pipes_struct *get_next_internal_pipe(pipes_struct *p)
{
return p->next;
}
@@ -118,11 +133,11 @@
Find first available pipe slot.
****************************************************************************/
-pipes_struct *open_rpc_pipe_p(char *pipe_name,
+smb_np_struct *open_rpc_pipe_p(char *pipe_name,
connection_struct *conn, uint16 vuid)
{
int i;
- pipes_struct *p;
+ smb_np_struct *p;
static int next_pipe;
DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
@@ -147,22 +162,17 @@
for (p = Pipes; p; p = p->next)
DEBUG(5,("open_rpc_pipe_p: name %s pnum=%x\n", p->name, p->pnum));
- p = (pipes_struct *)malloc(sizeof(*p));
+ p = (smb_np_struct *)malloc(sizeof(*p));
if (!p)
return NULL;
ZERO_STRUCTP(p);
- if ((p->mem_ctx = talloc_init()) == NULL) {
- DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
- SAFE_FREE(p);
- return NULL;
- }
+ p->np_state = (void*)make_internal_rpc_pipe_p(pipe_name, conn, vuid);
+ if (p->np_state == NULL) {
- if (!init_pipe_handle_list(p, pipe_name)) {
- DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
- talloc_destroy(p->mem_ctx);
+ DEBUG(0,("open_rpc_pipe_p: make_internal_rpc_pipe_p failed.\n"));
SAFE_FREE(p);
return NULL;
}
@@ -177,11 +187,6 @@
* change the type to UNMARSALLING before processing the stream.
*/
- if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
- DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
- return NULL;
- }
-
bitmap_set(bmap, i);
i += pipe_handle_offset;
@@ -197,6 +202,68 @@
p->max_trans_reply = 0;
+ fstrcpy(p->name, pipe_name);
+
+ DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
+ pipe_name, i, pipes_open));
+
+ chain_p = p;
+
+ /* OVERWRITE p as a temp variable, to display all open pipes */
+ for (p = Pipes; p; p = p->next)
+ DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+
+ return chain_p;
+}
+
+/****************************************************************************
+ * make an internal namedpipes structure
+****************************************************************************/
+
+pipes_struct *make_internal_rpc_pipe_p(char *pipe_name,
+ connection_struct *conn, uint16 vuid)
+{
+ pipes_struct *p;
+
+ DEBUG(4,("Create pipe requested %s\n", pipe_name));
+
+ p = (pipes_struct *)malloc(sizeof(*p));
+
+ if (!p)
+ return NULL;
+
+ ZERO_STRUCTP(p);
+
+ if ((p->mem_ctx = talloc_init()) == NULL) {
+ DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
+ SAFE_FREE(p);
+ return NULL;
+ }
+
+ if (!init_pipe_handle_list(p, pipe_name)) {
+ DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
+ talloc_destroy(p->mem_ctx);
+ SAFE_FREE(p);
+ return NULL;
+ }
+
+ /*
+ * Initialize the incoming RPC data buffer with one PDU worth of memory.
+ * We cheat here and say we're marshalling, as we intend to add incoming
+ * data directly into the prs_struct and we want it to auto grow. We will
+ * change the type to UNMARSALLING before processing the stream.
+ */
+
+ if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
+ DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
+ return NULL;
+ }
+
+ DLIST_ADD(InternalPipes, p);
+
+ p->conn = conn;
+ p->vuid = vuid;
+
p->ntlmssp_chal_flags = 0;
p->ntlmssp_auth_validated = False;
p->ntlmssp_auth_requested = False;
@@ -205,6 +272,11 @@
p->fault_state = False;
p->endian = RPC_LITTLE_ENDIAN;
+ ZERO_STRUCT(p->pipe_user);
+
+ p->pipe_user.uid = (uid_t)-1;
+ p->pipe_user.gid = (gid_t)-1;
+
/*
* Initialize the incoming RPC struct.
*/
@@ -225,23 +297,12 @@
*/
prs_init(&p->out_data.rdata, 0, p->mem_ctx, MARSHALL);
- ZERO_STRUCT(p->pipe_user);
-
- p->pipe_user.uid = (uid_t)-1;
- p->pipe_user.gid = (gid_t)-1;
-
fstrcpy(p->name, pipe_name);
-
- DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
- pipe_name, i, pipes_open));
-
- chain_p = p;
-
- /* OVERWRITE p as a temp variable, to display all open pipes */
- for (p = Pipes; p; p = p->next)
- DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
- return chain_p;
+ DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
+ pipe_name, pipes_open));
+
+ return p;
}
/****************************************************************************
@@ -254,8 +315,8 @@
p->in_data.pdu_needed_len = 0;
p->in_data.pdu_received_len = 0;
p->fault_state = True;
- DEBUG(10,("set_incoming_fault: Setting fault state on pipe %s : pnum = 0x%x\n",
- p->name, p->pnum ));
+ DEBUG(10,("set_incoming_fault: Setting fault state on pipe %s : vuid = 0x%x\n",
+ p->name, p->vuid ));
}
/****************************************************************************
@@ -712,10 +773,8 @@
Accepts incoming data on an rpc pipe.
****************************************************************************/
-ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
+ssize_t write_to_pipe(smb_np_struct *p, char *data, size_t n)
{
- size_t data_left = n;
-
DEBUG(6,("write_to_pipe: %x", p->pnum));
DEBUG(6,(" name: %s open: %s len: %d\n",
@@ -723,6 +782,18 @@
dump_data(50, data, n);
+ return write_to_internal_pipe((pipes_struct*)(p->np_state),
+ data, n);
+}
+
+/****************************************************************************
+ Accepts incoming data on an internal rpc pipe.
+****************************************************************************/
+
+ssize_t write_to_internal_pipe(pipes_struct *p, char *data, size_t n)
+{
+ size_t data_left = n;
+
while(data_left) {
ssize_t data_used;
@@ -753,11 +824,9 @@
have been prepared into arrays of headers + data stream sections.
****************************************************************************/
-ssize_t read_from_pipe(pipes_struct *p, char *data, size_t n)
+ssize_t read_from_pipe(smb_np_struct *p, char *data, size_t n,
+ BOOL *is_data_outstanding)
{
- uint32 pdu_remaining = 0;
- ssize_t data_returned = 0;
-
if (!p || !p->open) {
DEBUG(0,("read_from_pipe: pipe not open\n"));
return -1;
@@ -765,6 +834,32 @@
DEBUG(6,("read_from_pipe: %x", p->pnum));
+ return read_from_internal_pipe((pipes_struct*)(p->np_state),
+ data, n, is_data_outstanding);
+}
+
+/****************************************************************************
+ Replies to a request to read data from a pipe.
+
+ Headers are interspersed with the data at PDU intervals. By the time
+ this function is called, the start of the data could possibly have been
+ read by an SMBtrans (file_offset != 0).
+
+ Calling create_rpc_reply() here is a hack. The data should already
+ have been prepared into arrays of headers + data stream sections.
+****************************************************************************/
+
+ssize_t read_from_internal_pipe(pipes_struct *p, char *data, size_t n,
+ BOOL *is_data_outstanding)
+{
+ uint32 pdu_remaining = 0;
+ ssize_t data_returned = 0;
+
+ if (!p) {
+ DEBUG(0,("read_from_pipe: pipe not open\n"));
+ return -1;
+ }
+
DEBUG(6,(" name: %s len: %u\n", p->name, (unsigned int)n));
/*
@@ -839,6 +934,7 @@
out:
+ (*is_data_outstanding) = p->out_data.current_pdu_len > n;
return data_returned;
}
@@ -846,7 +942,7 @@
Wait device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
-BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
+BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
{
if (p == NULL)
return False;
@@ -870,7 +966,7 @@
Set device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
-BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
+BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state)
{
if (p == NULL)
return False;
@@ -894,21 +990,14 @@
Close an rpc pipe.
****************************************************************************/
-BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
+BOOL close_rpc_pipe_hnd(smb_np_struct *p, connection_struct *conn)
{
if (!p) {
DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
return False;
}
- prs_mem_free(&p->out_data.rdata);
- prs_mem_free(&p->in_data.data);
-
- if (p->mem_ctx)
- talloc_destroy(p->mem_ctx);
-
- /* Free the handles database. */
- close_policy_by_pipe(p);
+ close_internal_rpc_pipe_hnd((pipes_struct *)(p->np_state));
bitmap_clear(bmap, p->pnum - pipe_handle_offset);
@@ -919,9 +1008,38 @@
DLIST_REMOVE(Pipes, p);
+ ZERO_STRUCTP(p);
+
+ SAFE_FREE(p);
+
+ return True;
+}
+
+/****************************************************************************
+ Close an rpc pipe.
+****************************************************************************/
+
+BOOL close_internal_rpc_pipe_hnd(pipes_struct *p)
+{
+ if (!p) {
+ DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
+ return False;
+ }
+
+ prs_mem_free(&p->out_data.rdata);
+ prs_mem_free(&p->in_data.data);
+
+ if (p->mem_ctx)
+ talloc_destroy(p->mem_ctx);
+
+ /* Free the handles database. */
+ close_policy_by_pipe(p);
+
delete_nt_token(&p->pipe_user.nt_user_token);
SAFE_FREE(p->pipe_user.groups);
+ DLIST_REMOVE(InternalPipes, p);
+
ZERO_STRUCTP(p);
SAFE_FREE(p);
@@ -933,7 +1051,7 @@
Find an rpc pipe given a pipe handle in a buffer and an offset.
****************************************************************************/
-pipes_struct *get_rpc_pipe_p(char *buf, int where)
+smb_np_struct *get_rpc_pipe_p(char *buf, int where)
{
int pnum = SVAL(buf,where);
@@ -947,9 +1065,9 @@
Find an rpc pipe given a pipe handle.
****************************************************************************/
-pipes_struct *get_rpc_pipe(int pnum)
+smb_np_struct *get_rpc_pipe(int pnum)
{
- pipes_struct *p;
+ smb_np_struct *p;
DEBUG(4,("search for pipe pnum=%x\n", pnum));
@@ -966,3 +1084,4 @@
return NULL;
}
+
Index: rpc_server/srv_spoolss_nt.c
===================================================================
RCS file: /cvsroot/samba/source/rpc_server/srv_spoolss_nt.c,v
retrieving revision 1.237
diff -u -u -r1.237 srv_spoolss_nt.c
--- rpc_server/srv_spoolss_nt.c 12 Jan 2002 02:37:54 -0000 1.237
+++ rpc_server/srv_spoolss_nt.c 15 Jan 2002 11:00:59 -0000
@@ -633,7 +633,7 @@
*/
hl = NULL;
- for ( p = get_first_pipe(); p; get_next_pipe(p)) {
+ for ( p = get_first_internal_pipe(); p; get_next_internal_pipe(p)) {
if (strequal(p->name, "spoolss")) {
hl = p->pipe_handles;
break;
Index: script/mkproto.awk
===================================================================
RCS file: /cvsroot/samba/source/script/mkproto.awk,v
retrieving revision 1.58
diff -u -u -r1.58 mkproto.awk
--- script/mkproto.awk 19 Dec 2001 12:21:10 -0000 1.58
+++ script/mkproto.awk 15 Jan 2002 11:00:59 -0000
@@ -114,7 +114,7 @@
{
gotstart = 0;
- if( $0 ~ /^const|^connection_struct|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
+ if( $0 ~ /^const|^connection_struct|^pipes_struct|^smb_np_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
gotstart = 1;
}
Index: smbd/ipc.c
===================================================================
RCS file: /cvsroot/samba/source/smbd/ipc.c,v
retrieving revision 1.178
diff -u -u -r1.178 ipc.c
--- smbd/ipc.c 5 Nov 2001 00:02:37 -0000 1.178
+++ smbd/ipc.c 15 Jan 2002 11:01:00 -0000
@@ -163,8 +163,9 @@
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
-static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
+static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p)
{
+ BOOL is_data_outstanding;
char *rdata = malloc(p->max_trans_reply);
int data_len;
@@ -173,12 +174,13 @@
return False;
}
- if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
+ if((data_len = read_from_pipe( p, rdata, p->max_trans_reply,
+ &is_data_outstanding)) < 0) {
SAFE_FREE(rdata);
return False;
}
- send_trans_reply(outbuf, NULL, 0, rdata, data_len, p->out_data.current_pdu_len > data_len);
+ send_trans_reply(outbuf, NULL, 0, rdata, data_len, is_data_outstanding);
SAFE_FREE(rdata);
return True;
@@ -188,7 +190,7 @@
WaitNamedPipeHandleState
****************************************************************************/
-static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
+static BOOL api_WNPHS(char *outbuf, smb_np_struct *p, char *param, int param_len)
{
uint16 priority;
@@ -211,7 +213,7 @@
SetNamedPipeHandleState
****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
+static BOOL api_SNPHS(char *outbuf, smb_np_struct *p, char *param, int param_len)
{
uint16 id;
@@ -259,7 +261,7 @@
int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
BOOL reply = False;
- pipes_struct *p = NULL;
+ smb_np_struct *p = NULL;
int pnum;
int subcommand;
Index: smbd/nttrans.c
===================================================================
RCS file: /cvsroot/samba/source/smbd/nttrans.c,v
retrieving revision 1.143
diff -u -u -r1.143 nttrans.c
--- smbd/nttrans.c 4 Jan 2002 21:11:35 -0000 1.143
+++ smbd/nttrans.c 15 Jan 2002 11:01:03 -0000
@@ -466,7 +466,7 @@
static int nt_open_pipe(char *fname, connection_struct *conn,
char *inbuf, char *outbuf, int *ppnum)
{
- pipes_struct *p = NULL;
+ smb_np_struct *p = NULL;
uint16 vuid = SVAL(inbuf, smb_uid);
int i;
Index: smbd/pipes.c
===================================================================
RCS file: /cvsroot/samba/source/smbd/pipes.c,v
retrieving revision 1.74
diff -u -u -r1.74 pipes.c
--- smbd/pipes.c 18 Dec 2001 02:09:57 -0000 1.74
+++ smbd/pipes.c 15 Jan 2002 11:01:04 -0000
@@ -45,7 +45,7 @@
pstring fname;
pstring pipe_name;
uint16 vuid = SVAL(inbuf, smb_uid);
- pipes_struct *p;
+ smb_np_struct *p;
int smb_ofun = SVAL(inbuf,smb_vwv8);
int size=0,fmode=0,mtime=0,rmode=0;
int i;
@@ -116,7 +116,7 @@
****************************************************************************/
int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
size_t numtowrite = SVAL(inbuf,smb_vwv1);
int nwritten;
int outsize;
@@ -154,7 +154,7 @@
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
+ smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
size_t numtowrite = SVAL(inbuf,smb_vwv10);
int nwritten = -1;
int smb_doff = SVAL(inbuf, smb_vwv11);
@@ -210,11 +210,13 @@
****************************************************************************/
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
+ smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
int smb_maxcnt = SVAL(inbuf,smb_vwv5);
int smb_mincnt = SVAL(inbuf,smb_vwv6);
int nread = -1;
char *data;
+ BOOL unused;
+
/* we don't use the offset given to use for pipe reads. This
is deliberate, instead we always return the next lump of
data on the pipe */
@@ -228,7 +230,7 @@
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
- nread = read_from_pipe(p, data, smb_maxcnt);
+ nread = read_from_pipe(p, data, smb_maxcnt, &unused);
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -248,7 +250,7 @@
****************************************************************************/
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
{
- pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
int outsize = set_message(outbuf,0,0,True);
if (!p)
-------------- next part --------------
Index: lib/util_sock.c
===================================================================
RCS file: /cvsroot/samba/source/lib/util_sock.c,v
retrieving revision 1.48
diff -u -u -r1.48 util_sock.c
--- lib/util_sock.c 15 Jan 2002 01:37:12 -0000 1.48
+++ lib/util_sock.c 15 Jan 2002 11:00:43 -0000
@@ -194,6 +194,115 @@
return(ret);
}
+/*******************************************************************
+ checks if read data is outstanding.
+ ********************************************************************/
+int read_data_outstanding(int fd, unsigned int time_out)
+{
+ int selrtn;
+ fd_set fds;
+ struct timeval timeout;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ timeout.tv_sec = (time_t) (time_out / 1000);
+ timeout.tv_usec = (long)(1000 * (time_out % 1000));
+
+ selrtn = sys_select(fd + 1, &fds, &timeout);
+
+ if (selrtn <= 0)
+ {
+ return selrtn;
+ }
+ return FD_ISSET(fd, &fds) ? 1 : 0;
+}
+
+/****************************************************************************
+ Read data from a fd with a timout in msec.
+mincount = if timeout, minimum to read before returning
+maxcount = number to be read.
+time_out = timeout in milliseconds
+****************************************************************************/
+
+ssize_t read_with_timeout(int fd, char *buf, size_t mincnt, size_t maxcnt,
+ unsigned int time_out)
+{
+ ssize_t readret;
+ size_t nread = 0;
+
+ /* just checking .... */
+ if (maxcnt <= 0)
+ return (0);
+
+ /* Blocking read */
+ if (time_out <= 0)
+ {
+ if (mincnt == 0)
+ mincnt = maxcnt;
+
+ while (nread < mincnt)
+ {
+#ifdef WITH_SSL
+ if (fd == sslFd)
+ {
+ readret =
+ SSL_read(ssl, buf + nread,
+ maxcnt - nread);
+ }
+ else
+ {
+ readret =
+ read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = read(fd, buf + nread, maxcnt - nread);
+#endif /* WITH_SSL */
+
+ if (readret <= 0)
+ return readret;
+
+ nread += readret;
+ }
+ return ((ssize_t) nread);
+ }
+
+ /* Most difficult - timeout read */
+ /* If this is ever called on a disk file and
+ mincnt is greater then the filesize then
+ system performance will suffer severely as
+ select always returns true on disk files */
+
+ for (nread = 0; nread < mincnt;)
+ {
+ int selrtn = read_data_outstanding(fd, time_out);
+
+ if (selrtn <= 0)
+ return selrtn;
+
+#ifdef WITH_SSL
+ if (fd == sslFd)
+ {
+ readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+ }
+ else
+ {
+ readret = read(fd, buf + nread, maxcnt - nread);
+ }
+#else /* WITH_SSL */
+ readret = read(fd, buf + nread, maxcnt - nread);
+#endif /* WITH_SSL */
+
+ if (readret <= 0)
+ return readret;
+
+ nread += readret;
+ }
+
+ /* Return the number we got */
+ return ((ssize_t) nread);
+}
+
/****************************************************************************
Read data from a socket with a timout in msec.
mincount = if timeout, minimum to read before returning
@@ -306,87 +415,6 @@
/* Return the number we got */
return (ssize_t)nread;
-}
-
-/****************************************************************************
- Read data from a fd with a timout in msec.
- mincount = if timeout, minimum to read before returning
- maxcount = number to be read.
- time_out = timeout in milliseconds
-****************************************************************************/
-
-ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
-{
- fd_set fds;
- int selrtn;
- ssize_t readret;
- size_t nread = 0;
- struct timeval timeout;
-
- /* just checking .... */
- if (maxcnt <= 0)
- return(0);
-
- /* Blocking read */
- if (time_out <= 0) {
- if (mincnt == 0) mincnt = maxcnt;
-
- while (nread < mincnt) {
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
-#endif /* WITH_SSL */
-
- if (readret <= 0)
- return readret;
-
- nread += readret;
- }
- return((ssize_t)nread);
- }
-
- /* Most difficult - timeout read */
- /* If this is ever called on a disk file and
- mincnt is greater then the filesize then
- system performance will suffer severely as
- select always returns true on disk files */
-
- /* Set initial timeout */
- timeout.tv_sec = (time_t)(time_out / 1000);
- timeout.tv_usec = (long)(1000 * (time_out % 1000));
-
- for (nread=0; nread < mincnt; ) {
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- selrtn = sys_select_intr(fd+1,&fds,&timeout);
-
- if(selrtn <= 0)
- return selrtn;
-
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
-#endif /* WITH_SSL */
-
- if (readret <= 0)
- return readret;
-
- nread += readret;
- }
-
- /* Return the number we got */
- return((ssize_t)nread);
}
/****************************************************************************
More information about the samba-technical
mailing list