summaryrefslogtreecommitdiff
path: root/source3/lib/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util.c')
-rw-r--r--source3/lib/util.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 22c1c3e43d..812e59769e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -2270,7 +2270,7 @@ int read_smb_length(int fd,char *inbuf,int timeout)
/****************************************************************************
- read an smb from a fd and return it's length
+ read an smb from a fd.
The timeout is in milli seconds
****************************************************************************/
BOOL receive_smb(int fd,char *buffer,int timeout)
@@ -2300,6 +2300,88 @@ BOOL receive_smb(int fd,char *buffer,int timeout)
return(True);
}
+#ifdef USE_OPLOCKS
+/****************************************************************************
+ Do a select on an two fd's - with timeout.
+
+ If the first smbfd is ready then read an smb from it.
+ if the second (loopback UDP) fd is ready then read a message
+ from it and setup the buffer header to identify the length
+ and from address.
+ Returns False on timeout or error.
+ Else returns True.
+
+The timeout is in milli seconds
+****************************************************************************/
+BOOL receive_message_or_smb(int smbfd, int oplock_fd,
+ char *buffer, int buffer_len,
+ int timeout, BOOL *got_smb)
+{
+ fd_set fds;
+ int selrtn;
+ struct timeval to;
+
+ *got_smb = False;
+
+ FD_ZERO(&fds);
+ FD_SET(smbfd,&fds);
+ FD_SET(oplock_fd,&fds);
+
+ to.tv_sec = timeout / 1000;
+ to.tv_usec = (timeout % 1000) * 1000;
+
+ selrtn = sys_select(&fds,timeout>0?&to:NULL);
+
+ /* Check if error */
+ if(selrtn == -1) {
+ /* something is wrong. Maybe the socket is dead? */
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+
+ /* Did we timeout ? */
+ if (selrtn == 0) {
+ smb_read_error = READ_TIMEOUT;
+ return False;
+ }
+
+ if (FD_ISSET(smbfd,&fds))
+ {
+ *got_smb = True;
+ return receive_smb(smbfd, buffer, 0);
+ }
+ else
+ {
+ /*
+ * Read a udp message.
+ */
+ struct sockaddr_in from;
+ int fromlen = sizeof(from);
+ int32 msg_len = 0;
+ uint16 port = 0;
+
+ msg_len = recvfrom(oplock_fd, &buffer[6+sizeof(struct in_addr)],
+ buffer_len - (6 + sizeof(struct in_addr)), 0,
+ (struct sockaddr *)&from, &fromlen);
+
+ if(msg_len < 0)
+ {
+ DEBUG(0,("Invalid loopback packet ! (%s).\n",strerror(errno)));
+ return False;
+ }
+
+ port = ntohs(from.sin_port);
+
+ /* Setup the message header */
+ SIVAL(buffer,0,msg_len);
+ SSVAL(buffer,4,port);
+ memcpy(&buffer[6],(char *)&from.sin_addr,sizeof(struct in_addr));
+
+ }
+
+ return True;
+}
+#endif /* USE_OPLOCKS */
/****************************************************************************
send an smb to a fd