Пример #1
0
char *smb_readline(char *prompt, void (*callback)(void), 
		   char **(completion_fn)(const char *text, int start, int end))
{
	char *ret;
	int fd = fileno(stdin);

#if HAVE_LIBREADLINE

	/*
	 * Current versions of readline on Linux seem to have
	 * problems with EOF on a pipe.
	 */

	if (isatty(fd)) {
		if (completion_fn)
			rl_attempted_completion_function = completion_fn;

		if (callback)
			rl_event_hook = (Function *)callback;
		ret = readline(prompt);
		if (ret && *ret)
			add_history(ret);
		return ret;
	} else
#endif
	{
		fd_set fds;
		extern FILE *dbf;
		static pstring line;
		struct timeval timeout;

		fprintf(dbf, "%s", prompt);
		fflush(dbf);

		while (1) {
			timeout.tv_sec = 5;
			timeout.tv_usec = 0;

			FD_ZERO(&fds);
			FD_SET(fd,&fds);
	
			if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
				ret = fgets(line, sizeof(line), stdin);
				return ret;
			}
			if (callback)
				callback();
		}
	}
}
Пример #2
0
static void filter_child(int c, struct in_addr dest_ip)
{
	int s;

	/* we have a connection from a new client, now connect to the server */
	s = open_socket_out(SOCK_STREAM, &dest_ip, 445, LONG_CONNECT_TIMEOUT);

	if (s == -1) {
		d_printf("Unable to connect to %s\n", inet_ntoa(dest_ip));
		exit(1);
	}

	while (c != -1 || s != -1) {
		fd_set fds;
		int num;
		
		FD_ZERO(&fds);
		if (s != -1) FD_SET(s, &fds);
		if (c != -1) FD_SET(c, &fds);

		num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
		if (num <= 0) continue;
		
		if (c != -1 && FD_ISSET(c, &fds)) {
			if (!receive_smb(c, packet, BUFFER_SIZE, 0)) {
				d_printf("client closed connection\n");
				exit(0);
			}
			filter_request(packet);
			if (!send_smb(s, packet)) {
				d_printf("server is dead\n");
				exit(1);
			}			
		}
		if (s != -1 && FD_ISSET(s, &fds)) {
			if (!receive_smb(s, packet, BUFFER_SIZE, 0)) {
				d_printf("server closed connection\n");
				exit(0);
			}
			filter_reply(packet);
			if (!send_smb(c, packet)) {
				d_printf("client is dead\n");
				exit(1);
			}			
		}
	}
	d_printf("Connection closed\n");
	exit(0);
}
Пример #3
0
static void start_filter(char *desthost)
{
	int s, c;
	struct in_addr dest_ip;

	CatchChild();

	/* start listening on port 445 locally */
	s = open_socket_in(SOCK_STREAM, 445, 0, 0, True);
	
	if (s == -1) {
		d_printf("bind failed\n");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		d_printf("listen failed\n");
	}

	if (!resolve_name(desthost, &dest_ip, 0x20)) {
		d_printf("Unable to resolve host %s\n", desthost);
		exit(1);
	}

	while (1) {
		fd_set fds;
		int num;
		struct sockaddr addr;
		socklen_t in_addrlen = sizeof(addr);
		
		FD_ZERO(&fds);
		FD_SET(s, &fds);

		num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
		if (num > 0) {
			c = accept(s, &addr, &in_addrlen);
			if (c != -1) {
				if (fork() == 0) {
					close(s);
					filter_child(c, dest_ip);
					exit(0);
				} else {
					close(c);
				}
			}
		}
	}
}
Пример #4
0
static BOOL irix_oplock_msg_waiting(fd_set *fds)
{
	int selrtn;
	fd_set myfds;
	struct timeval to;

	if (oplock_pipe_read == -1)
		return False;

	if (fds) {
		return FD_ISSET(oplock_pipe_read, fds);
	}

	/* Do a zero-time select. We just need to find out if there
	 * are any outstanding messages. We use sys_select_intr as
	 * we need to ignore any signals. */

	FD_ZERO(&myfds);
	FD_SET(oplock_pipe_read, &myfds);

	to = timeval_set(0, 0);
	selrtn = sys_select_intr(oplock_pipe_read+1,&myfds,NULL,NULL,&to);
	return (selrtn == 1) ? True : False;
}
Пример #5
0
ssize_t read_socket_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);
	
	smb_read_error = 0;
	
	/* Blocking read */
	if (time_out <= 0) {
		if (mincnt == 0) mincnt = maxcnt;
		
		while (nread < mincnt) {
			readret = sys_read(fd, buf + nread, maxcnt - nread);
			
			if (readret == 0) {
				DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
				smb_read_error = READ_EOF;
				return -1;
			}
			
			if (readret == -1) {
				DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
				smb_read_error = READ_ERROR;
				return -1;
			}
			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,NULL,NULL,&timeout);
		
		/* Check if error */
		if (selrtn == -1) {
			/* something is wrong. Maybe the socket is dead? */
			DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
			smb_read_error = READ_ERROR;
			return -1;
		}
		
		/* Did we timeout ? */
		if (selrtn == 0) {
			DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
			smb_read_error = READ_TIMEOUT;
			return -1;
		}
		
		readret = sys_read(fd, buf+nread, maxcnt-nread);
		
		if (readret == 0) {
			/* we got EOF on the file descriptor */
			DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
			smb_read_error = READ_EOF;
			return -1;
		}
		
		if (readret == -1) {
			/* the descriptor is probably dead */
			DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
			smb_read_error = READ_ERROR;
			return -1;
		}
		
		nread += readret;
	}
	
	/* Return the number we got */
	return (ssize_t)nread;
}
Пример #6
0
BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
			 int timeout, int *fd_index, int *fd)
{
	int i, resulting_index, res;
	int *sockets;
	BOOL good_connect;

	fd_set r_fds, wr_fds;
	struct timeval tv;
	int maxfd;

	int connect_loop = 10000; /* 10 milliseconds */

	timeout *= 1000; 	/* convert to microseconds */

	sockets = SMB_MALLOC_ARRAY(int, num_addrs);

	if (sockets == NULL)
		return False;

	resulting_index = -1;

	for (i=0; i<num_addrs; i++)
		sockets[i] = -1;

	for (i=0; i<num_addrs; i++) {
		sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
		if (sockets[i] < 0)
			goto done;
		set_blocking(sockets[i], False);
	}

 connect_again:
	good_connect = False;

	for (i=0; i<num_addrs; i++) {

		if (sockets[i] == -1)
			continue;

		if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),
			    sizeof(*addrs)) == 0) {
			/* Rather unlikely as we are non-blocking, but it
			 * might actually happen. */
			resulting_index = i;
			goto done;
		}

		if (errno == EINPROGRESS || errno == EALREADY ||
		    errno == EAGAIN) {
			/* These are the error messages that something is
			   progressing. */
			good_connect = True;
		} else if (errno != 0) {
			/* There was a direct error */
			close(sockets[i]);
			sockets[i] = -1;
		}
	}

	if (!good_connect) {
		/* All of the connect's resulted in real error conditions */
		goto done;
	}

	/* Lets see if any of the connect attempts succeeded */

	maxfd = 0;
	FD_ZERO(&wr_fds);
	FD_ZERO(&r_fds);

	for (i=0; i<num_addrs; i++) {
		if (sockets[i] == -1)
			continue;
		FD_SET(sockets[i], &wr_fds);
		FD_SET(sockets[i], &r_fds);
		if (sockets[i]>maxfd)
			maxfd = sockets[i];
	}

	tv.tv_sec = 0;
	tv.tv_usec = connect_loop;

	res = sys_select_intr(maxfd+1, &r_fds, &wr_fds, NULL, &tv);

	if (res < 0)
		goto done;

	if (res == 0)
		goto next_round;

	for (i=0; i<num_addrs; i++) {

		if (sockets[i] == -1)
			continue;

		/* Stevens, Network Programming says that if there's a
		 * successful connect, the socket is only writable. Upon an
		 * error, it's both readable and writable. */

		if (FD_ISSET(sockets[i], &r_fds) &&
		    FD_ISSET(sockets[i], &wr_fds)) {
			/* readable and writable, so it's an error */
			close(sockets[i]);
			sockets[i] = -1;
			continue;
		}

		if (!FD_ISSET(sockets[i], &r_fds) &&
		    FD_ISSET(sockets[i], &wr_fds)) {
			/* Only writable, so it's connected */
			resulting_index = i;
			goto done;
		}
	}

 next_round:

	timeout -= connect_loop;
	if (timeout <= 0)
		goto done;
	connect_loop *= 1.5;
	if (connect_loop > timeout)
		connect_loop = timeout;
	goto connect_again;

 done:
	for (i=0; i<num_addrs; i++) {
		if (i == resulting_index)
			continue;
		if (sockets[i] >= 0)
			close(sockets[i]);
	}

	if (resulting_index >= 0) {
		*fd_index = resulting_index;
		*fd = sockets[*fd_index];
		set_blocking(*fd, True);
	}

	free(sockets);

	return (resulting_index >= 0);
}
Пример #7
0
ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endtime)
{
	ssize_t ret;
	size_t total=0;

	smb_read_error = 0;

	while (total < N) {

		if (endtime != NULL) {
			fd_set r_fds;
			struct timeval timeout;
			int selrtn;

			if (!timeout_until(&timeout, endtime)) {
				DEBUG(10,("read_data_until: read timed out\n"));
				smb_read_error = READ_TIMEOUT;
				return -1;
			}

			FD_ZERO(&r_fds);
			FD_SET(fd, &r_fds);

			/* Select but ignore EINTR. */
			selrtn = sys_select_intr(fd+1, &r_fds, NULL, NULL, &timeout);
			if (selrtn == -1) {
				/* something is wrong. Maybe the socket is dead? */
				DEBUG(0,("read_data_until: select error = %s.\n", strerror(errno) ));
				smb_read_error = READ_ERROR;
				return -1;
			}

			/* Did we timeout ? */
			if (selrtn == 0) {
				DEBUG(10,("read_data_until: select timed out.\n"));
				smb_read_error = READ_TIMEOUT;
				return -1;
			}
		}

		ret = sys_read(fd,buffer + total,N - total);

		if (ret == 0) {
			DEBUG(10,("read_data_until: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
			smb_read_error = READ_EOF;
			return 0;
		}

		if (ret == -1) {
			if (errno == EAGAIN) {
				/* Non-blocking socket with no data available. Try select again. */
				continue;
			}
			DEBUG(0,("read_data_until: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
			smb_read_error = READ_ERROR;
			return -1;
		}
		total += ret;
	}
	return (ssize_t)total;
}