aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/inetd/builtins.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/usr.sbin/inetd/builtins.c b/usr.sbin/inetd/builtins.c
index 7516ed0af808..c32a98d3339c 100644
--- a/usr.sbin/inetd/builtins.c
+++ b/usr.sbin/inetd/builtins.c
@@ -343,14 +343,14 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
struct timeval tv = {
10,
0
- };
+ }, to;
struct passwd *pw = NULL;
fd_set fdset;
- char buf[BUFSIZE], *cp = NULL, *p, **av, *osname = NULL, garbage[7];
+ char buf[BUFSIZE], *cp = NULL, *p, **av, *osname = NULL, garbage[7], e;
char *fallback = NULL;
socklen_t socklen;
ssize_t ssize;
- size_t size;
+ size_t size, bufsiz;
int c, fflag = 0, nflag = 0, rflag = 0, argc = 0, usedfallback = 0;
int gflag = 0, getcredfail = 0, onreadlen;
u_short lport, fport;
@@ -450,19 +450,42 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
* "local_port , foreign_port\r\n" (with local being the
* server's port and foreign being the client's.)
*/
+ gettimeofday(&to, NULL);
+ to.tv_sec += tv.tv_sec;
+ if ((to.tv_usec += tv.tv_usec) >= 1000000) {
+ to.tv_usec -= 1000000;
+ to.tv_sec++;
+ }
+
+ size = 0;
+ bufsiz = sizeof(buf) - 1;
FD_ZERO(&fdset);
- FD_SET(s, &fdset);
- if (select(s + 1, &fdset, NULL, NULL, &tv) == -1)
- iderror(0, 0, s, errno);
- if (ioctl(s, FIONREAD, &onreadlen) == -1)
- iderror(0, 0, s, errno);
- if (onreadlen >= sizeof(buf))
- onreadlen = sizeof(buf) - 1;
- ssize = read(s, buf, (size_t)onreadlen);
- if (ssize == -1)
- iderror(0, 0, s, errno);
- buf[ssize] = '\0';
- if (sscanf(buf, "%hu , %hu", &lport, &fport) != 2)
+ while (bufsiz > 0 && (size == 0 || buf[size - 1] != '\n')) {
+ gettimeofday(&tv, NULL);
+ tv.tv_sec = to.tv_sec - tv.tv_sec;
+ tv.tv_usec = to.tv_usec - tv.tv_usec;
+ if (tv.tv_usec < 0) {
+ tv.tv_usec += 1000000;
+ tv.tv_sec--;
+ }
+ if (tv.tv_sec < 0)
+ break;
+ FD_SET(s, &fdset);
+ if (select(s + 1, &fdset, NULL, NULL, &tv) == -1)
+ iderror(0, 0, s, errno);
+ if (ioctl(s, FIONREAD, &onreadlen) == -1)
+ iderror(0, 0, s, errno);
+ if (onreadlen > bufsiz)
+ onreadlen = bufsiz;
+ ssize = read(s, &buf[size], (size_t)onreadlen);
+ if (ssize == -1)
+ iderror(0, 0, s, errno);
+ bufsiz -= ssize;
+ size += ssize;
+ }
+ buf[size] = '\0';
+ /* Read two characters, and check for a delimiting character */
+ if (sscanf(buf, "%hu , %hu%c", &lport, &fport, &e) != 3 || isdigit(e))
iderror(0, 0, s, 0);
if (gflag) {
cp = garbage;