Linux HAM/Amateur Radio development
 help / color / mirror / Atom feed
* [PATCH] node and libax25io nonblocking
@ 2003-02-17 20:56 Jeroen Vreeken
  2003-02-17 21:21 ` Tomi Manninen
  2003-02-17 22:13 ` Tomi Manninen
  0 siblings, 2 replies; 13+ messages in thread
From: Jeroen Vreeken @ 2003-02-17 20:56 UTC (permalink / raw)
  To: linux-hams; +Cc: csmall, tomi.manninen

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]

Hi,

I got a bit tired of waiting for a new node release....
The attached patches are against libax25-0.0.10 and node-0.3.0.
The libax25 patch is basicly the same I posted a while back with the buffer
check added and a few changes to axio_puts(), axio_gets() and
axio_getline().

	Jeroen

[-- Attachment #2: libax25-nonblock.diff --]
[-- Type: application/octet-stream, Size: 8934 bytes --]

diff -ruN libax25-0.0.10/ChangeLog libax25-0.0.10.rxq/ChangeLog
--- libax25-0.0.10/ChangeLog	Thu Mar 28 23:09:15 2002
+++ libax25-0.0.10.rxq/ChangeLog	Fri Feb 14 00:00:57 2003
@@ -1,3 +1,6 @@
+	* libax25io handles nonblocking io correctly. (PE1RXQ)
+	  THIS BREAKS PRACTICLY EVERY APP USING THIS LIBRARY, FIX THEM!!!
+
 libax25 0.0.10
 
  	* Fixed byte counting in flush_obuf() (PE1RXQ)
diff -ruN libax25-0.0.10/ax25io.c libax25-0.0.10.rxq/ax25io.c
--- libax25-0.0.10/ax25io.c	Thu Mar 28 22:57:51 2002
+++ libax25-0.0.10.rxq/ax25io.c	Mon Feb 17 21:22:21 2003
@@ -33,6 +33,9 @@
 	if ((new = calloc(1, sizeof(ax25io))) == NULL)
 		return NULL;
 
+	if (paclen > AXBUFLEN)
+		paclen = AXBUFLEN;
+
 	new->ifd	= in;
 	new->ofd	= out;
 	new->eolmode	= EOLMODE_TEXT;
@@ -134,38 +137,24 @@
 static int flush_obuf(ax25io *p)
 {
 	int ret;
-	int count=0;
 
 	if (p->optr == 0)
 		return 0;
 
-	do {
-		if ((ret = write(p->ofd, p->obuf, p->optr < p->paclen ? p->optr : p->paclen)) < 0)
+	if ((ret = write(p->ofd, p->obuf, p->optr < p->paclen ? p->optr : p->paclen)) < 0)
 			return -1;
 
-		if (ret < p->optr)
-			memmove(p->obuf, &p->obuf[ret], p->optr - ret);
-		p->optr -= ret;
-		count += ret;
-
-		/* If buffer full block until there is room */
-		if (p->optr>=AXBUFLEN) {
-			fd_set fdset;
-
-			FD_ZERO(&fdset);
-			FD_SET(p->ofd, &fdset);
-			if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0)
-				return -1;
-		}
-	} while (p->optr>=AXBUFLEN);
+	if (ret && ret < p->optr)
+		memmove(p->obuf, &p->obuf[ret], p->optr - ret);
+	p->optr -= ret;
 
-	return count;
+	return ret;
 }
 
 int axio_flush(ax25io *p)
 {
 	int flushed=0;
-	fd_set fdset;
+	int ret;
 
 #ifdef HAVE_ZLIB_H
 	if (p->zptr) {
@@ -227,18 +216,23 @@
 #endif
 
 	while (p->optr) {
-		FD_ZERO(&fdset);
-		FD_SET(p->ofd, &fdset);
-		if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0)
+		/* Return on error or if zero bytes written */
+		if ((ret=flush_obuf(p))<=0)
 			return -1;
-		flushed+=flush_obuf(p);
+		flushed+=ret;
 	}
 
 	return flushed;
 }
 
-static int rsendchar(unsigned char c, ax25io *p)
+static int rsend(unsigned char *c, int len, ax25io *p)
 {
+	/* Don't go further until there is space */
+	if (p->paclen <= p->optr) {
+		if (flush_obuf(p)<=0)
+			return -1;
+	}
+
 #ifdef HAVE_ZLIB_H
 	if (p->zptr) {
 		struct compr_s *z = (struct compr_s *) p->zptr;
@@ -255,9 +249,8 @@
 		/*
 		 * One new character to input.
 		 */
-		z->char_buf = c;
-		z->zout.next_in = &z->char_buf;
-		z->zout.avail_in = 1;
+		z->zout.next_in = c;
+		z->zout.avail_in = len;
 		/*
 		 * Now loop until deflate returns with avail_out != 0
 		 */
@@ -298,18 +291,26 @@
 
 		} while (z->zout.avail_out == 0);
 
-		return c;
+		return len;
 	}
 #endif
 
-	p->obuf[p->optr++] = c;
+	if (p->optr+len<AXBUFLEN) {
+		memcpy(p->obuf+p->optr, c, len);
+		p->optr+=len;
+	} else {
+		errno=EAGAIN;
+		return -1;
+	}
 
-	if (p->optr >= p->paclen && flush_obuf(p) < 0)
+	if (p->optr >= p->paclen && flush_obuf(p) < 0) {
 		return -1;
+	}
 
-	return c;
+	return len;
 }
 
+
 /* --------------------------------------------------------------------- */
 
 static int recv_ibuf(ax25io *p)
@@ -423,32 +424,25 @@
 
 int axio_putc(int c, ax25io *p)
 {
-	char *cp;
+	char cp;
 
 	if (p->telnetmode && c == IAC) {
-		if (rsendchar(IAC, p) == -1)
-			return -1;
-		return rsendchar(IAC, p);
+		static char iac[]={IAC, IAC};
+		return rsend(iac, 2, p);
 	}
 
 	if (c == INTERNAL_EOL) {
 		if (p->eolmode == EOLMODE_BINARY)
-			return rsendchar('\n', p);
+			return rsend("\n", 1, p);
 		else
-			for (cp = p->eol; *cp; cp++)
-				if (rsendchar(*cp, p) == -1)
-					return -1;
-		return 1;
+			return rsend(p->eol, strlen(p->eol), p);
 	}
 
-	if (p->eolmode == EOLMODE_TEXT && c == '\n') {
-		for (cp = p->eol; *cp; cp++)
-			if (rsendchar(*cp, p) == -1)
-				return -1;
-		return 1;
-	}
+	if (p->eolmode == EOLMODE_TEXT && c == '\n')
+		return rsend(p->eol, strlen(p->eol), p);
 
-	return rsendchar(c & 0xff, p);
+	cp=c&0xff;
+	return rsend(&cp, 1, p);
 }
 
 int axio_getc(ax25io *p)
@@ -500,28 +494,34 @@
 			 * ECHO and TRAPSIG).
 			 */
 			if (opt == TELOPT_LINEMODE && p->tn_linemode) {
-				rsendchar(IAC,                      p);
-				rsendchar(SB,                       p);
-				rsendchar(TELOPT_LINEMODE,          p);
-				rsendchar(LM_MODE,                  p);
-				rsendchar(MODE_EDIT | MODE_TRAPSIG, p);
-				rsendchar(IAC,                      p);
-				rsendchar(SE,                       p);
+				static char telopt_linemode[]={
+				    IAC,
+				    SB,
+				    TELOPT_LINEMODE,
+				    LM_MODE,
+				    MODE_EDIT | MODE_TRAPSIG,
+				    IAC,
+				    SE };
+				if (rsend(telopt_linemode, 7, p)<0)
+					return -1;
 			} else {
-				rsendchar(IAC,  p);
-				rsendchar(DONT, p);
-				rsendchar(opt,  p);
+				static char iac_dont[]={IAC, DONT, 0};
+				iac_dont[2]=opt;
+				if (rsend(iac_dont, 3, p)<0)
+					return -1;
 			}
 			axio_flush(p);
 			break;
 		case DO:
 			switch (opt) {
-			case TELOPT_SGA:
-				rsendchar(IAC,  p);
-				rsendchar(WILL, p);
-				rsendchar(opt,  p);
+			case TELOPT_SGA: {
+				static char iac_will[]={IAC, WILL, 0};
+				iac_will[2]=opt;
+				if (rsend(iac_will, 3, p)<0)
+					return -1;
 				axio_flush(p);
 				break;
+			}
 			case TELOPT_ECHO:
 				/*
 				 * If we want echo then just silently
@@ -530,13 +530,15 @@
 				if (p->tn_echo)
 					break;
 				/* Note fall-through */
-			default:
-				rsendchar(IAC,  p);
-				rsendchar(WONT, p);
-				rsendchar(opt,  p);
+			default: {
+				static char iac_wont[]={IAC, WONT, 0};
+				iac_wont[2]=opt;
+				if (rsend(iac_wont, 3, p)<0)
+					return -1;	
 				axio_flush(p);
 				break;
 			}
+			}
 			break;
 		case IAC:	/* Escaped IAC */
 			return IAC;
@@ -574,43 +576,62 @@
 
 /* --------------------------------------------------------------------- */
 
-char *axio_gets(char *buf, int buflen, ax25io *p)
+int axio_gets(char *buf, int buflen, ax25io *p)
 {
 	int c, len = 0;
 
 	while (len < (buflen - 1)) {
 		c = axio_getc(p);
 		if (c == -1) {
-			if (len > 0) {
-				buf[len] = 0;
-				return buf;
-			} else
-				return NULL;
+			return -len;
 		}
-		/* NUL also interpreted as EOL */
+		/* NULL also interpreted as EOL */
 		if (c == '\n' || c == '\r' || c == 0) {
 			buf[len] = 0;
-			return buf;
+			errno=0;
+			return len;
 		}
 		buf[len++] = c;
 	}
 	buf[buflen - 1] = 0;
-	return buf;
+	errno=0;
+	return len;
 }
 
+static int buf_usage=0;
+static char buf[AXBUFLEN];
+
 char *axio_getline(ax25io *p)
 {
-	static char buf[AXBUFLEN];
-
-	return axio_gets(buf, AXBUFLEN, p);
+	int ret;
+	
+	ret=axio_gets(buf+buf_usage, AXBUFLEN-buf_usage, p);
+	if (ret > 0) {
+		buf_usage=0;
+		return buf;
+	}
+	if (ret==0 && errno==0) {
+		buf_usage=0;
+		return buf;
+	}
+	buf_usage+=ret;
+	return NULL;
 }
 
 int axio_puts(const char *s, ax25io *p)
 {
+	int count=0;
+
 	while (*s)
-		if (axio_putc(*s++, p) == -1)
-			return -1;
-	return 0;
+		if (axio_putc(*s++, p) == -1) {
+			if (errno!=EAGAIN)
+				return -1;
+			else
+				break;
+		} else {
+			count++;
+		}
+	return count;
 }
 
 /* --------------------------------------------------------------------- */
@@ -639,29 +660,34 @@
 }
 
 /* --------------------------------------------------------------------- */
+static char do_linemode[]={IAC, DO, TELOPT_LINEMODE};
 
-void axio_tn_do_linemode(ax25io *p)
+int axio_tn_do_linemode(ax25io *p)
 {
-	rsendchar(IAC,             p);
-	rsendchar(DO,              p);
-	rsendchar(TELOPT_LINEMODE, p);
+	if (rsend(do_linemode, 3, p)<0)
+		return -1;
 	p->tn_linemode = 1;
+	return 0;
 }
 
-void axio_tn_will_echo(ax25io *p)
+static char will_echo[]={IAC, WILL, TELOPT_ECHO};
+
+int axio_tn_will_echo(ax25io *p)
 {
-	rsendchar(IAC,         p);
-	rsendchar(WILL,        p);
-	rsendchar(TELOPT_ECHO, p);
+	if (rsend(will_echo, 3, p)<0)
+		return -1;
 	p->tn_echo = 1;
+	return 0;
 }
 
-void axio_tn_wont_echo(ax25io *p)
+static char wont_echo[]={IAC, WONT, TELOPT_ECHO};
+
+int axio_tn_wont_echo(ax25io *p)
 {
-	rsendchar(IAC,         p);
-	rsendchar(WONT,        p);
-	rsendchar(TELOPT_ECHO, p);
+	if (rsend(wont_echo, 3, p)<0)
+		return -1;
 	p->tn_echo = 0;
+	return 0;
 }
 
 /* --------------------------------------------------------------------- */
diff -ruN libax25-0.0.10/ax25io.h libax25-0.0.10.rxq/ax25io.h
--- libax25-0.0.10/ax25io.h	Tue Apr 10 03:54:09 2001
+++ libax25-0.0.10.rxq/ax25io.h	Mon Feb 17 20:55:18 2003
@@ -73,13 +73,13 @@
 extern int axio_putc(int, ax25io *);
 
 extern char *axio_getline(ax25io *);
-extern char *axio_gets(char *, int, ax25io *);
+extern int axio_gets(char *, int, ax25io *);
 extern int axio_puts(const char *, ax25io *);
 
 extern int axio_printf(ax25io *, const char *, ...);
 
-extern void axio_tn_do_linemode(ax25io *);
-extern void axio_tn_will_echo(ax25io *);
-extern void axio_tn_wont_echo(ax25io *);
+extern int axio_tn_do_linemode(ax25io *);
+extern int axio_tn_will_echo(ax25io *);
+extern int axio_tn_wont_echo(ax25io *);
 
 #endif _AX25IO_H

[-- Attachment #3: node-0.3.0-nonblock.diff --]
[-- Type: application/octet-stream, Size: 12953 bytes --]

diff -ruN node-0.3.0/HISTORY node-0.3.0.rxq/HISTORY
--- node-0.3.0/HISTORY	Mon Jul  5 19:35:49 1999
+++ node-0.3.0.rxq/HISTORY	Fri Feb 14 00:03:26 2003
@@ -1,3 +1,6 @@
+			- Fixed Nonblocking response for new libax25io.
+			  (PE1RXQ)
+
 0.3.0   05 Jul 1999	- Initial version using the new dynamic libax25.
 			- Moved the IO code to libax25.
 
diff -ruN node-0.3.0/extcmd.c node-0.3.0.rxq/extcmd.c
--- node-0.3.0/extcmd.c	Sun Jun  6 22:24:34 1999
+++ node-0.3.0.rxq/extcmd.c	Fri Feb 14 00:03:26 2003
@@ -49,8 +49,9 @@
 {
 	ax25io *iop;
 	int pipe_in[2], pipe_out[2];
-	int pid, c;
-	fd_set fdset;
+	int pid, cn=0, cp=0;
+	fd_set fdset, fdsetno;
+	int pend_nodew=0, pend_nodef=0, pend_pipew=0, pend_pipef=0;
 
 	if (pipe(pipe_in) == -1) {
 		node_perror("pipe_extcmd: pipe_in", errno);
@@ -102,31 +103,66 @@
 	}
 	while (1) {
 		FD_ZERO(&fdset);
+		FD_ZERO(&fdsetno);
 		FD_SET(STDIN_FILENO, &fdset);
 		FD_SET(pipe_out[0], &fdset);
-		if (select(32, &fdset, 0, 0, 0) == -1) {
+		if (pend_nodew || pend_nodef)
+			FD_SET(NodeIo->ofd, &fdsetno);
+		if (pend_pipew || pend_pipef)
+			FD_SET(iop->ofd, &fdsetno);
+		if (select(32, &fdset, &fdsetno, 0, 0) == -1) {
 			node_perror("pipe_extcmd: select", errno);
 			break;
 		}
-		if (FD_ISSET(STDIN_FILENO, &fdset)) {
+		/* Try to write pending char to pipe */
+		if (FD_ISSET(iop->ofd, &fdsetno)) {
+			if (axio_putc(cn, iop) != -1)
+				pend_pipew=0;
+			else if (errno != EAGAIN)
+				break;
+		}
+		if (FD_ISSET(STDIN_FILENO, &fdset) && !pend_pipew) {
 			alarm(ConnTimeout);
-			while((c = axio_getc(NodeIo)) != -1)
-				axio_putc(c, iop);
+			while((cn = axio_getc(NodeIo)) != -1)
+				if (axio_putc(cn, iop)==-1 && errno==EAGAIN) {
+					pend_pipew=1;
+					break;
+				}
 			if (errno != EAGAIN)
 				break;
 		}
-		if (FD_ISSET(pipe_out[0], &fdset)) {
+		if (FD_ISSET(NodeIo->ofd, &fdsetno)) {
+			if (axio_putc(cp, NodeIo) != -1)
+				pend_pipew=0;
+			else if (errno != EAGAIN)
+				break;
+		}
+		if (FD_ISSET(pipe_out[0], &fdset) && !pend_nodew) {
 			alarm(ConnTimeout);
-			while((c = axio_getc(iop)) != -1)
-				axio_putc(c, NodeIo);
+			while((cp = axio_getc(iop)) != -1)
+				if (axio_putc(cp, NodeIo)==-1 && errno==EAGAIN) {
+					pend_nodew=1;
+					break;
+				}
 			if (errno != EAGAIN) {
                                 if (errno)
                                         node_msg("%s", strerror(errno));
                                 break;
 			}
 		}
-		axio_flush(NodeIo);
-		axio_flush(iop);
+		if (axio_flush(NodeIo)==-1) {
+			if (errno==EAGAIN)
+				pend_nodef=1;
+			else
+				break;
+		} else
+			pend_nodef=0;
+		if (axio_flush(iop)==-1) {
+			if (errno==EAGAIN)
+				pend_pipef=1;
+			else
+				break;
+		}
 	}
 	axio_end(iop);
 end:
diff -ruN node-0.3.0/gateway.c node-0.3.0.rxq/gateway.c
--- node-0.3.0/gateway.c	Sun Jun  6 22:24:34 1999
+++ node-0.3.0.rxq/gateway.c	Mon Feb 17 01:19:22 2003
@@ -272,7 +272,18 @@
 	}
 	User.dl_type = family;
 	node_msg("Trying %s... Type <RETURN> to abort", print_dl(&User));
-	axio_flush(NodeIo);
+	while (axio_flush(NodeIo)==-1) {
+		if (errno!=EAGAIN) {
+			close(fd);
+			return NULL;
+		}
+		FD_ZERO(&write_fdset);
+		FD_SET(NodeIo->ofd, &write_fdset);
+		if (select(NodeIo->ofd+1, 0, &write_fdset, 0, 0)==-1) {
+			close(fd);
+			return NULL;
+		}
+	}
 	User.state = STATE_TRYING;
 	update_user();
 	/*
@@ -335,7 +346,18 @@
 			 escape < 32 ? "CTRL-" : "",
 			 escape < 32 ? (escape + 'A' - 1) : escape);
 
-	axio_flush(NodeIo);
+	while (axio_flush(NodeIo)==-1) {
+		if (errno!=EAGAIN) {
+			close(fd);
+			return NULL;
+		}
+		FD_ZERO(&write_fdset);
+		FD_SET(NodeIo->ofd, &write_fdset);
+		if (select(NodeIo->ofd+1, 0, &write_fdset, 0, 0)==-1) {
+			close(fd);
+			return NULL;
+		}
+	}
 	log(L_GW, "Connected to %s", print_dl(&User));
 	if ((riop = axio_init(fd, fd, paclen, eol)) == NULL) {
 		node_perror("connect_to: Initializing I/O failed", errno);
@@ -352,9 +374,10 @@
 int do_connect(int argc, char **argv)
 {
 	ax25io *riop;
-	int c, family, stay, escape, compress;
-	fd_set fdset;
+	int c, family, stay, escape, compress, cp=0, cn=0;
+	fd_set fdset, fdsetno;
 	char *connstr = NULL;
+	int pend_pipew=0, pend_pipef=0, pend_nodew=0, pend_nodef=0, pend_getline=0;
 
 	stay = ReConnectTo;
 	if (!strcasecmp(argv[argc - 1], "s")) {
@@ -406,7 +429,15 @@
 		axio_tnmode(riop, 1);
 	if (connstr) {
 		axio_printf(riop, "%s\n", connstr);
-		axio_flush(riop);
+		while (axio_flush(riop)==-1) {
+			if (errno!=EAGAIN)
+				return 0;
+			FD_ZERO(&fdset);
+			FD_SET(riop->ofd, &fdset);
+			if (select(riop->ofd+1, 0, &fdset, 0, 0)==-1) {
+				return 0;
+			}
+		}
 	}
 	/*
 	 * If eol conventions are compatible, switch to binary mode,
@@ -421,16 +452,30 @@
 	}
 	while (1) {
 		FD_ZERO(&fdset);
+		FD_ZERO(&fdsetno);
 		FD_SET(riop->ifd, &fdset);
 		FD_SET(STDIN_FILENO, &fdset);
-		if (select(32, &fdset, 0, 0, 0) == -1) {
+		if (pend_nodew || pend_nodef)
+			FD_SET(NodeIo->ofd, &fdsetno);
+		if (pend_pipew || pend_pipef)
+			FD_SET(riop->ofd, &fdsetno);
+		if (select(32, &fdset, &fdsetno, 0, 0) == -1) {
 			node_perror("do_connect: select", errno);
 			break;
 		}
-		if (FD_ISSET(riop->ifd, &fdset)) {
+		if (FD_ISSET(NodeIo->ofd, &fdsetno)) {
+			if (axio_putc(cp, NodeIo) != -1)
+				pend_nodew=0;
+			else if (errno != EAGAIN)
+				break;
+		}
+		if (FD_ISSET(riop->ifd, &fdset) && !pend_nodew) {
 			alarm(ConnTimeout);
-			while((c = axio_getc(riop)) != -1)
-				axio_putc(c, NodeIo);
+			while((cp = axio_getc(riop)) != -1)
+				if (axio_putc(cp, NodeIo)==-1 && errno==EAGAIN) {
+					pend_nodew=1;
+					break;
+				}
 			if (errno != EAGAIN) {
 				switch (errno) {
 				case 0:
@@ -451,25 +496,52 @@
 				break;
 			}
 		}
-		if (FD_ISSET(STDIN_FILENO, &fdset)) {
+		if (FD_ISSET(riop->ofd, &fdsetno)) {
+			if (axio_putc(cn, riop) != -1)
+				pend_pipew=0;
+			else if (errno != EAGAIN)
+				break;
+		}
+		if (FD_ISSET(STDIN_FILENO, &fdset) && pend_getline) {
+			if (axio_getline(NodeIo))
+				pend_getline=0;
+		}
+		if (FD_ISSET(STDIN_FILENO, &fdset) && !pend_pipew && !pend_getline) {
 			alarm(ConnTimeout);
-			while((c = axio_getc(NodeIo)) != -1) {
-				if (escape != -1 && c == escape)
+			while((cn = axio_getc(NodeIo)) != -1) {
+				if (escape != -1 && cn == escape)
 					break;
-				axio_putc(c, riop);
+				if (axio_putc(cn, riop)==-1 && errno==EAGAIN) {
+					pend_pipew=1;
+					break;
+				}
 			}
-			if (escape != -1 && c == escape) {
+			if (escape != -1 && cn == escape) {
 				axio_eolmode(NodeIo, EOLMODE_TEXT);
-				axio_getline(NodeIo);
-				break;
+				if (!axio_getline(NodeIo))
+					pend_getline=1;
+				else
+					break;
 			}
 			if (errno != EAGAIN) {
 				stay = 0;
 				break;
 			}
 		}
-		axio_flush(riop);
-		axio_flush(NodeIo);
+		if (axio_flush(riop)==-1) {
+			if (errno==EAGAIN)
+				pend_pipef=1;
+			else
+				break;
+		} else
+			pend_pipef=0;
+		if (axio_flush(NodeIo)==-1) {
+			if (errno==EAGAIN)
+				pend_nodef=1;
+			else
+				break;
+		} else
+			pend_nodef=0;
 	}
 	axio_end(riop);
 	log(L_GW, "Disconnected from %s", print_dl(&User));
@@ -488,6 +560,7 @@
 	ax25io *riop;
 	int c;
 	char *name, *addr[3], *cp;
+	fd_set fdset;
 
 	if (argc < 2) {
 		name = "";
@@ -507,9 +580,26 @@
 		if (fcntl(riop->ifd, F_SETFL, 0) == -1)
 			node_perror("do_finger: fcntl - fd", errno);
 		axio_printf(riop, "%s\n", name);
-		axio_flush(riop);
+		while (axio_flush(riop)==-1) {
+			if (errno!=EAGAIN)
+				break;
+			FD_ZERO(&fdset);
+			FD_SET(riop->ofd, &fdset);
+			if (select(riop->ofd+1, 0, &fdset, 0, 0)==-1)
+				break;
+		}
 		while((c = axio_getc(riop)) != -1)
-			axio_putc(c, NodeIo);
+			if (axio_putc(c, NodeIo)==-1) {
+				if (errno!=EAGAIN)
+					break;
+				FD_ZERO(&fdset);
+				FD_SET(NodeIo->ofd, &fdset);
+				/* This is one way traffic, we are just going
+				   to sit and wait until we can send again */
+				if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+					break;
+				axio_putc(c, NodeIo);
+			}
 		axio_end(riop);
 		node_msg("Reconnected to %s", HostName);
 	}
@@ -615,7 +705,14 @@
 		return 0;
 	}
 	node_msg("Pinging %s... Type <RETURN> to abort", inet_ntoa(to.sin_addr));
-	axio_flush(NodeIo);
+	while (axio_flush(NodeIo)==-1) {
+		if (errno!=EAGAIN)
+			return 0;
+		FD_ZERO(&fdset);
+		FD_SET(NodeIo->ofd, &fdset);
+		if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+			return 0;
+	}
 	strncpy(User.dl_name, hp->h_name, 31);
 	User.dl_name[31] = 0;
 	User.dl_type = AF_INET;
diff -ruN node-0.3.0/node.c node-0.3.0.rxq/node.c
--- node-0.3.0/node.c	Sun Jun  6 22:24:34 1999
+++ node-0.3.0.rxq/node.c	Mon Feb 17 01:18:42 2003
@@ -90,6 +90,7 @@
 	int paclen;
 	FILE *fp;
 	int invalid_cmds = 0;
+	fd_set fdset;
 
 	signal(SIGALRM, signal_handler);
 	signal(SIGTERM, signal_handler);
@@ -170,7 +171,14 @@
 #endif
 	if (User.ul_type == AF_INET) {
 		axio_tnmode(NodeIo, 1);
-		axio_tn_do_linemode(NodeIo);
+		while (axio_tn_do_linemode(NodeIo)==-1) {
+			if (errno!=EAGAIN)
+				return 1;
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ofd, &fdset);
+			if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+				return 1;
+		}
 	}
 	init_nodecmds();
 	if (read_config() == -1) {
@@ -192,9 +200,22 @@
 	login_user();
 	if (User.call[0] == 0) {
 		nprintf("\n%s (%s)\n\nlogin: ", VERSION, HostName);
-		axio_flush(NodeIo);
+		while (axio_flush(NodeIo)==-1) {
+			if (errno!=EAGAIN)
+				return 1;
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ofd, &fdset);
+			if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+				return 1;
+		}
 		alarm(300L);			/* 5 min timeout */
-		if ((p = axio_getline(NodeIo)) == NULL)
+		while ((p = axio_getline(NodeIo)) == NULL && errno==EAGAIN) {
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ifd, &fdset);
+			if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1)
+				return 1;
+		}
+		if (p == NULL)
 			logout("User disconnected");
 		alarm(0L);
 		strncpy(User.call, p, 9);
@@ -215,13 +236,39 @@
 	} else if (strcmp(pw, "*") != 0) {
 		nputs("Password: ");
 		if (User.ul_type == AF_INET) {
-			axio_tn_will_echo(NodeIo);
+			while (axio_tn_will_echo(NodeIo)==-1) {
+				if (errno!=EAGAIN)
+					return 1;
+				FD_ZERO(&fdset);
+				FD_SET(NodeIo->ofd, &fdset);
+				if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+					return 1;
+			}
 			axio_eolmode(NodeIo, EOLMODE_BINARY);
 		}
-		axio_flush(NodeIo);
-		p = axio_getline(NodeIo);
+		while (axio_flush(NodeIo)==-1) {
+			if (errno!=EAGAIN)
+				return 1;
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ofd, &fdset);
+			if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+				return 1;
+		}
+		while ((p = axio_getline(NodeIo)) == NULL && errno==EAGAIN) {
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ifd, &fdset);
+			if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1)
+				return 1;
+		}
 		if (User.ul_type == AF_INET) {
-			axio_tn_wont_echo(NodeIo);
+			while (axio_tn_wont_echo(NodeIo)==-1) {
+				if (errno!=EAGAIN)
+					return 1;
+				FD_ZERO(&fdset);
+				FD_SET(NodeIo->ofd, &fdset);
+				if (select(NodeIo->ofd+1, 0,&fdset, 0, 0)==-1)
+					return 1;
+			}
 			axio_eolmode(NodeIo, EOLMODE_TEXT);
 			nputs("\n");
 		}
@@ -243,7 +290,14 @@
 	put_prompt();
 	log(L_LOGIN, "%s @ %s logged in", User.call, User.ul_name);
 	while (1) {
-		axio_flush(NodeIo);
+		while (axio_flush(NodeIo)==-1) {
+			if (errno!=EAGAIN)
+				return 1;
+			FD_ZERO(&fdset);
+			FD_SET(NodeIo->ofd, &fdset);
+			if (select(NodeIo->ofd+1, 0, &fdset, 0, 0)==-1)
+				return 1;
+		}
 		User.state = STATE_IDLE;
 		time(&User.cmdtime);
 		update_user();
@@ -251,6 +305,13 @@
 		if ((p = axio_getline(NodeIo)) == NULL) {
 			if (errno == EINTR)
 				continue;
+			if (errno == EAGAIN) {
+				FD_ZERO(&fdset);
+				FD_SET(NodeIo->ifd, &fdset);
+				if (select(NodeIo->ifd+1, &fdset, 0, 0, 0)==-1)
+					return 1;
+				continue;
+			}
 			logout("User disconnected");
 		}
 		alarm(IdleTimeout);
diff -ruN node-0.3.0/nodeusers.c node-0.3.0.rxq/nodeusers.c
--- node-0.3.0/nodeusers.c	Sun Jun  6 22:24:34 1999
+++ node-0.3.0.rxq/nodeusers.c	Mon Feb 17 01:13:58 2003
@@ -67,11 +67,21 @@
 		fprintf(stderr, "nodeusers: axio_init failed\r\n");
 		return 1;
 	}
-	if (inet && axio_getline(NodeIo) == NULL) {
-		if (logging)
-			syslog(LOG_ERR, "axio_getline: %m");
-		axio_end(NodeIo);
-		return 1;
+	if (inet) {
+		while (axio_getline(NodeIo) == NULL) {
+			if (errno==EAGAIN) {
+				fd_set fdset;
+			
+				FD_ZERO(&fdset);
+				FD_SET(NodeIo->ifd, &fdset);
+				select(NodeIo->ifd+1, &fdset, 0, 0, 0);
+				continue;
+			}
+			if (logging)
+				syslog(LOG_ERR, "axio_getline: %m");
+			axio_end(NodeIo);
+			return 1;
+		}
 	}
 	n = user_count();
 	nprintf("\n%s - %d user%s.\n\n", VERSION, n, n == 1 ? "" : "s");
diff -ruN node-0.3.0/util.c node-0.3.0.rxq/util.c
--- node-0.3.0/util.c	Wed Apr 21 22:38:43 1999
+++ node-0.3.0.rxq/util.c	Fri Feb 14 00:12:03 2003
@@ -15,7 +15,15 @@
 
 int nputs(const char *str)
 {
-	return axio_puts(str, NodeIo);
+	int i=0, ret;
+	
+	while (i<strlen(str)) {
+		ret=axio_puts(str+i, NodeIo);
+		if (ret==-1)
+			return -1;
+		i+=ret;
+	}
+	return 0;
 }
 
 int nprintf(const char *fmt, ...)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-17 20:56 [PATCH] node and libax25io nonblocking Jeroen Vreeken
@ 2003-02-17 21:21 ` Tomi Manninen
  2003-02-17 22:13 ` Tomi Manninen
  1 sibling, 0 replies; 13+ messages in thread
From: Tomi Manninen @ 2003-02-17 21:21 UTC (permalink / raw)
  To: Jeroen Vreeken; +Cc: linux-hams, csmall

On Mon, 17 Feb 2003 21:56:08 +0100 Jeroen Vreeken <pe1rxq@amsat.org> wrote:

> I got a bit tired of waiting for a new node release....
> The attached patches are against libax25-0.0.10 and node-0.3.0.
> The libax25 patch is basicly the same I posted a while back with the
> buffer check added and a few changes to axio_puts(), axio_gets() and
> axio_getline().

Well, I'm a bit tired of things too...

Anyway, I did a fix to node a few weeks ago and I was going to send it
to you (jeroen) for testing. I don't have a setup to test it properly
here. I'll look at your fix and tell you what I think. Basically I don't
think libax25 should be touched, other than the bugs introduced in 0.0.10
need to be fixed (ie. go back to 0.0.9 behaviour).

-- 
Tomi Manninen         Internet:  oh2bns@sral.fi
OH2BNS                AX.25:     oh2bns@oh2rbi.fin.eu
KP20ME04              Amprnet:   oh2bns@oh2rbi.ampr.org

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-17 20:56 [PATCH] node and libax25io nonblocking Jeroen Vreeken
  2003-02-17 21:21 ` Tomi Manninen
@ 2003-02-17 22:13 ` Tomi Manninen
  2003-02-17 23:14   ` Jeroen Vreeken
  1 sibling, 1 reply; 13+ messages in thread
From: Tomi Manninen @ 2003-02-17 22:13 UTC (permalink / raw)
  To: Jeroen Vreeken; +Cc: linux-hams, csmall

On Mon, 17 Feb 2003, Jeroen Vreeken wrote:

> The libax25 patch is basicly the same I posted a while back with the buffer
> check added and a few changes to axio_puts(), axio_gets() and
> axio_getline().

Question: is this different from the patch I sent you and Craig a few 
months back? The version that should be in the CVS now (I haven't checked 
the CVS).

The approach you have used for fixing node seems after a quick look 
similar to what I had done, but there is one thing I need to discuss with 
you. I'll get back to you on that later.

You have covered a few cases that I had missed but also you have a 
few cases that I think are not needed. (It shouldn't be necessary to add 
any extra select() loops or other blocking measures when the socket 
already is blocking...)

More comments tomorrow.

-- 
Tomi Manninen           Internet:  oh2bns@sral.fi
OH2BNS                  AX.25:     oh2bns@oh2rbi.fin.eu
KP20ME04                Amprnet:   oh2bns@oh2rbi.ampr.org


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-17 22:13 ` Tomi Manninen
@ 2003-02-17 23:14   ` Jeroen Vreeken
  2003-02-17 23:17     ` Tomi Manninen
  0 siblings, 1 reply; 13+ messages in thread
From: Jeroen Vreeken @ 2003-02-17 23:14 UTC (permalink / raw)
  To: linux-hams

On 2003.02.17 23:13:48 +0100 Tomi Manninen wrote:
> On Mon, 17 Feb 2003, Jeroen Vreeken wrote:
> 
> > The libax25 patch is basicly the same I posted a while back with the
> buffer
> > check added and a few changes to axio_puts(), axio_gets() and
> > axio_getline().
> 
> Question: is this different from the patch I sent you and Craig a few 
> months back? The version that should be in the CVS now (I haven't checked
> 
> the CVS).

Not much, I took your check for the buffer length during init but haven't
taken in the other stuff (mostly IAC rewrite). The big difference is
axio_puts(), axio_gets() and axio_getline() these weren't done yet.

	Jeroen


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-17 23:14   ` Jeroen Vreeken
@ 2003-02-17 23:17     ` Tomi Manninen
  2003-02-18 22:35       ` Jeroen Vreeken
  0 siblings, 1 reply; 13+ messages in thread
From: Tomi Manninen @ 2003-02-17 23:17 UTC (permalink / raw)
  To: Jeroen Vreeken; +Cc: linux-hams

On Tue, 18 Feb 2003, Jeroen Vreeken wrote:

> > Question: is this different from the patch I sent you and Craig a few 
> > months back? The version that should be in the CVS now (I haven't checked
> > the CVS).
> 
> Not much, I took your check for the buffer length during init but haven't
> taken in the other stuff (mostly IAC rewrite). The big difference is
> axio_puts(), axio_gets() and axio_getline() these weren't done yet.

Ok, could you please take those too, or better make the patch against the 
CVS version (assuming the CVS version was updated) ?

-- 
Tomi Manninen           Internet:  oh2bns@sral.fi
OH2BNS                  AX.25:     oh2bns@oh2rbi.fin.eu
KP20ME04                Amprnet:   oh2bns@oh2rbi.ampr.org


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-17 23:17     ` Tomi Manninen
@ 2003-02-18 22:35       ` Jeroen Vreeken
  2003-02-18 22:37         ` Tomi Manninen
  0 siblings, 1 reply; 13+ messages in thread
From: Jeroen Vreeken @ 2003-02-18 22:35 UTC (permalink / raw)
  To: tpm; +Cc: csmall, linux-hams

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

On 2003.02.18 00:17:50 +0100 Tomi Manninen wrote:
> 
> Ok, could you please take those too, or better make the patch against the
> 
> CVS version (assuming the CVS version was updated) ?

Attached the same patch against what should have been in the CVS :)

btw getline changed a bit, the buffer is no longer global but in the ax25io
structure so each connection has its own (this is not a problem yet, but
might become one...)

	Jeroen

[-- Attachment #2: libax25-0.0.10-nonblock.diff --]
[-- Type: application/octet-stream, Size: 2612 bytes --]

diff -ruN libax25-0.0.10.oh2bns/ax25io.c libax25-0.0.10.merge/ax25io.c
--- libax25-0.0.10.oh2bns/ax25io.c	Tue Feb 18 23:30:34 2003
+++ libax25-0.0.10.merge/ax25io.c	Tue Feb 18 23:29:27 2003
@@ -44,6 +44,7 @@
 	new->ofd = out;
 	new->eolmode = EOLMODE_TEXT;
 	new->paclen = paclen;
+	new->gbuf_usage = 0;
 
 	strncpy(new->eol, eol, 3);
 	new->eol[3] = 0;
@@ -564,43 +565,55 @@
 
 /* --------------------------------------------------------------------- */
 
-char *axio_gets(char *buf, int buflen, ax25io *p)
+int axio_gets(char *buf, int buflen, ax25io *p)
 {
 	int c, len = 0;
 
 	while (len < (buflen - 1)) {
 		c = axio_getc(p);
 		if (c == -1) {
-			if (len > 0) {
-				buf[len] = 0;
-				return buf;
-			} else
-				return NULL;
+			return -len;
 		}
 		/* NUL also interpreted as EOL */
 		if (c == '\n' || c == '\r' || c == 0) {
 			buf[len] = 0;
-			return buf;
+			errno = 0;
+			return len;
 		}
 		buf[len++] = c;
 	}
 	buf[buflen - 1] = 0;
-	return buf;
+	errno = 0;
+	return len;
 }
 
 char *axio_getline(ax25io *p)
 {
-	static char buf[AXBUFLEN];
+	int ret;
 
-	return axio_gets(buf, AXBUFLEN, p);
+	ret = axio_gets(p->gbuf + p->gbuf_usage, AXBUFLEN - p->gbuf_usage, p);
+	if (ret > 0 || (ret == 0 && errno == 0)) {
+		p->gbuf_usage = 0;
+		return p->gbuf;
+	}
+	p->gbuf_usage += ret;
+	return NULL;
 }
 
 int axio_puts(const char *s, ax25io *p)
 {
+	int count=0;
+
 	while (*s)
-		if (axio_putc(*s++, p) == -1)
-			return -1;
-	return 0;
+		if (axio_putc(*s++, p) == -1) {
+			if (errno != EAGAIN)
+				return -1;
+			else
+				break;
+		} else {
+			count++;
+		}
+	return count;
 }
 
 /* --------------------------------------------------------------------- */
diff -ruN libax25-0.0.10.oh2bns/ax25io.h libax25-0.0.10.merge/ax25io.h
--- libax25-0.0.10.oh2bns/ax25io.h	Tue Feb 18 23:30:34 2003
+++ libax25-0.0.10.merge/ax25io.h	Tue Feb 18 23:28:44 2003
@@ -33,6 +33,8 @@
 	int paclen;		/* paclen                               */
 	unsigned char ibuf[AXBUFLEN];	/* input buffer			*/
 	unsigned char obuf[AXBUFLEN];	/* output buffer		*/
+	unsigned char gbuf[AXBUFLEN];	/* getline buffer		*/
+	int gbuf_usage;		/* getline buffer usage			*/
 	int iptr;		/* input pointer                        */
 	int optr;		/* output pointer                       */
 	void *zptr;		/* pointer to the compression struct	*/
@@ -73,7 +75,7 @@
 extern int axio_putc(int, ax25io *);
 
 extern char *axio_getline(ax25io *);
-extern char *axio_gets(char *, int, ax25io *);
+extern int axio_gets(char *, int, ax25io *);
 extern int axio_puts(const char *, ax25io *);
 
 extern int axio_printf(ax25io *, const char *, ...);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-18 22:35       ` Jeroen Vreeken
@ 2003-02-18 22:37         ` Tomi Manninen
  2003-02-21 10:37           ` Craig Small
  0 siblings, 1 reply; 13+ messages in thread
From: Tomi Manninen @ 2003-02-18 22:37 UTC (permalink / raw)
  To: Jeroen Vreeken; +Cc: csmall, linux-hams

[-- Attachment #1: Type: TEXT/PLAIN, Size: 629 bytes --]

On Tue, 18 Feb 2003, Jeroen Vreeken wrote:

> Attached the same patch against what should have been in the CVS :)
> 
> btw getline changed a bit, the buffer is no longer global but in the ax25io
> structure so each connection has its own (this is not a problem yet, but
> might become one...)

Ok, after a very quick look this looks FB. And just in case Craig
misplaced the earlier patch I was talking about, I added it here. So first
my patch, then Jeroen's.

-- 
Tomi Manninen           Internet:  oh2bns@sral.fi
OH2BNS                  AX.25:     oh2bns@oh2rbi.fin.eu
KP20ME04                Amprnet:   oh2bns@oh2rbi.ampr.org

[-- Attachment #2: Type: TEXT/PLAIN, Size: 9096 bytes --]

diff -ru libax25-0.0.10.orig/ChangeLog libax25-0.0.10/ChangeLog
--- libax25-0.0.10.orig/ChangeLog	Fri Mar 29 00:09:15 2002
+++ libax25-0.0.10/ChangeLog	Tue Oct 15 20:39:25 2002
@@ -1,3 +1,6 @@
+	* libax25io handles nonblocking io correctly. (PE1RXQ)
+	  THIS BREAKS PRACTICLY EVERY APP USING THIS LIBRARY, FIX THEM!!!
+
 libax25 0.0.10
 
  	* Fixed byte counting in flush_obuf() (PE1RXQ)
diff -ru libax25-0.0.10.orig/ax25io.c libax25-0.0.10/ax25io.c
--- libax25-0.0.10.orig/ax25io.c	Thu Mar 28 23:57:51 2002
+++ libax25-0.0.10/ax25io.c	Tue Oct 15 22:59:00 2002
@@ -9,6 +9,10 @@
 #include "config.h"
 #include "ax25io.h"
 
+static inline int send_iac_iac(ax25io *p);
+static inline int send_iac_cmd(ax25io *p, char cmd, char opt);
+static inline int send_linemode(ax25io *p);
+
 static ax25io *Iolist = NULL;
 
 /* --------------------------------------------------------------------- */
@@ -17,10 +21,10 @@
 #include <zlib.h>
 
 struct compr_s {
-	int z_error;		/* "(de)compression error" flag		*/
-	unsigned char char_buf;	/* temporary character buffer		*/
-	z_stream zin;		/* decompressor structure		*/
-	z_stream zout;		/* compressor structure			*/
+	int z_error;		/* "(de)compression error" flag         */
+	unsigned char char_buf;	/* temporary character buffer           */
+	z_stream zin;		/* decompressor structure               */
+	z_stream zout;		/* compressor structure                 */
 };
 #endif
 
@@ -33,10 +37,13 @@
 	if ((new = calloc(1, sizeof(ax25io))) == NULL)
 		return NULL;
 
-	new->ifd	= in;
-	new->ofd	= out;
-	new->eolmode	= EOLMODE_TEXT;
-	new->paclen	= paclen;
+	if (paclen > AXBUFLEN)
+		paclen = AXBUFLEN;
+
+	new->ifd = in;
+	new->ofd = out;
+	new->eolmode = EOLMODE_TEXT;
+	new->paclen = paclen;
 
 	strncpy(new->eol, eol, 3);
 	new->eol[3] = 0;
@@ -94,7 +101,7 @@
 	}
 	return 0;
 #endif
-	/*ax25_errno = AX25IO_NO_Z_SUPPORT;*/
+	/* ax25_errno = AX25IO_NO_Z_SUPPORT; */
 	return -1;
 }
 
@@ -133,39 +140,28 @@
 
 static int flush_obuf(ax25io *p)
 {
-	int ret;
-	int count=0;
+	int ret, len;
 
 	if (p->optr == 0)
 		return 0;
 
-	do {
-		if ((ret = write(p->ofd, p->obuf, p->optr < p->paclen ? p->optr : p->paclen)) < 0)
-			return -1;
+	len = p->optr < p->paclen ? p->optr : p->paclen;
 
-		if (ret < p->optr)
-			memmove(p->obuf, &p->obuf[ret], p->optr - ret);
-		p->optr -= ret;
-		count += ret;
-
-		/* If buffer full block until there is room */
-		if (p->optr>=AXBUFLEN) {
-			fd_set fdset;
-
-			FD_ZERO(&fdset);
-			FD_SET(p->ofd, &fdset);
-			if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0)
-				return -1;
-		}
-	} while (p->optr>=AXBUFLEN);
+	if ((ret = write(p->ofd, p->obuf, len)) < 0)
+		return -1;
+
+	if (ret && ret < p->optr)
+		memmove(p->obuf, &p->obuf[ret], p->optr - ret);
+
+	p->optr -= ret;
 
-	return count;
+	return ret;
 }
 
 int axio_flush(ax25io *p)
 {
-	int flushed=0;
-	fd_set fdset;
+	int flushed = 0;
+	int ret;
 
 #ifdef HAVE_ZLIB_H
 	if (p->zptr) {
@@ -227,18 +223,23 @@
 #endif
 
 	while (p->optr) {
-		FD_ZERO(&fdset);
-		FD_SET(p->ofd, &fdset);
-		if (select(p->ofd+1, NULL, &fdset, NULL, NULL)<0)
+		/* Return on error or if zero bytes written */
+		if ((ret = flush_obuf(p)) <= 0)
 			return -1;
-		flushed+=flush_obuf(p);
+		flushed += ret;
 	}
 
 	return flushed;
 }
 
-static int rsendchar(unsigned char c, ax25io *p)
+static int rsend(unsigned char *c, int len, ax25io *p)
 {
+	/* Don't go further until there is space */
+	if (p->paclen <= p->optr) {
+		if (flush_obuf(p) <= 0)
+			return -1;
+	}
+
 #ifdef HAVE_ZLIB_H
 	if (p->zptr) {
 		struct compr_s *z = (struct compr_s *) p->zptr;
@@ -255,9 +256,8 @@
 		/*
 		 * One new character to input.
 		 */
-		z->char_buf = c;
-		z->zout.next_in = &z->char_buf;
-		z->zout.avail_in = 1;
+		z->zout.next_in = c;
+		z->zout.avail_in = len;
 		/*
 		 * Now loop until deflate returns with avail_out != 0
 		 */
@@ -298,18 +298,25 @@
 
 		} while (z->zout.avail_out == 0);
 
-		return c;
+		return len;
 	}
 #endif
 
-	p->obuf[p->optr++] = c;
+	if (p->optr + len < AXBUFLEN) {
+		memcpy(p->obuf + p->optr, c, len);
+		p->optr += len;
+	} else {
+		errno = EAGAIN;
+		return -1;
+	}
 
 	if (p->optr >= p->paclen && flush_obuf(p) < 0)
 		return -1;
 
-	return c;
+	return len;
 }
 
+
 /* --------------------------------------------------------------------- */
 
 static int recv_ibuf(ax25io *p)
@@ -423,32 +430,23 @@
 
 int axio_putc(int c, ax25io *p)
 {
-	char *cp;
+	char cp;
 
-	if (p->telnetmode && c == IAC) {
-		if (rsendchar(IAC, p) == -1)
-			return -1;
-		return rsendchar(IAC, p);
-	}
+	if (p->telnetmode && c == IAC)
+		return send_iac_iac(p);
 
 	if (c == INTERNAL_EOL) {
 		if (p->eolmode == EOLMODE_BINARY)
-			return rsendchar('\n', p);
+			return rsend("\n", 1, p);
 		else
-			for (cp = p->eol; *cp; cp++)
-				if (rsendchar(*cp, p) == -1)
-					return -1;
-		return 1;
+			return rsend(p->eol, strlen(p->eol), p);
 	}
 
-	if (p->eolmode == EOLMODE_TEXT && c == '\n') {
-		for (cp = p->eol; *cp; cp++)
-			if (rsendchar(*cp, p) == -1)
-				return -1;
-		return 1;
-	}
+	if (p->eolmode == EOLMODE_TEXT && c == '\n')
+		return rsend(p->eol, strlen(p->eol), p);
 
-	return rsendchar(c & 0xff, p);
+	cp = c & 0xff;
+	return rsend(&cp, 1, p);
 }
 
 int axio_getc(ax25io *p)
@@ -456,7 +454,7 @@
 	int c, opt;
 	char *cp;
 
-	opt = 0; /* silence warning */
+	opt = 0;		/* silence warning */
 
 	if ((c = rrecvchar(p)) == -1)
 		return -1;
@@ -468,7 +466,7 @@
 		if (c > 249 && c < 255 && (opt = rrecvchar(p)) == -1)
 			return -1;
 
-		switch(c) {
+		switch (c) {
 		case IP:
 		case ABORT:
 		case xEOF:
@@ -500,26 +498,19 @@
 			 * ECHO and TRAPSIG).
 			 */
 			if (opt == TELOPT_LINEMODE && p->tn_linemode) {
-				rsendchar(IAC,                      p);
-				rsendchar(SB,                       p);
-				rsendchar(TELOPT_LINEMODE,          p);
-				rsendchar(LM_MODE,                  p);
-				rsendchar(MODE_EDIT | MODE_TRAPSIG, p);
-				rsendchar(IAC,                      p);
-				rsendchar(SE,                       p);
+				if (send_linemode(p) < 0)
+					return -1;
 			} else {
-				rsendchar(IAC,  p);
-				rsendchar(DONT, p);
-				rsendchar(opt,  p);
+				if (send_iac_cmd(p, DONT, opt) < 0)
+					return -1;
 			}
 			axio_flush(p);
 			break;
 		case DO:
 			switch (opt) {
 			case TELOPT_SGA:
-				rsendchar(IAC,  p);
-				rsendchar(WILL, p);
-				rsendchar(opt,  p);
+				if (send_iac_cmd(p, WILL, opt) < 0)
+					return -1;
 				axio_flush(p);
 				break;
 			case TELOPT_ECHO:
@@ -531,9 +522,8 @@
 					break;
 				/* Note fall-through */
 			default:
-				rsendchar(IAC,  p);
-				rsendchar(WONT, p);
-				rsendchar(opt,  p);
+				if (send_iac_cmd(p, WONT, opt) < 0)
+					return -1;
 				axio_flush(p);
 				break;
 			}
@@ -640,29 +630,57 @@
 
 /* --------------------------------------------------------------------- */
 
-void axio_tn_do_linemode(ax25io *p)
+int axio_tn_do_linemode(ax25io *p)
 {
-	rsendchar(IAC,             p);
-	rsendchar(DO,              p);
-	rsendchar(TELOPT_LINEMODE, p);
+	if (send_iac_cmd(p, DO, TELOPT_LINEMODE) < 0)
+		return -1;
 	p->tn_linemode = 1;
+	return 0;
 }
 
-void axio_tn_will_echo(ax25io *p)
+int axio_tn_will_echo(ax25io *p)
 {
-	rsendchar(IAC,         p);
-	rsendchar(WILL,        p);
-	rsendchar(TELOPT_ECHO, p);
+	if (send_iac_cmd(p, WILL, TELOPT_ECHO) < 0)
+		return -1;
 	p->tn_echo = 1;
+	return 0;
 }
 
-void axio_tn_wont_echo(ax25io *p)
+int axio_tn_wont_echo(ax25io *p)
 {
-	rsendchar(IAC,         p);
-	rsendchar(WONT,        p);
-	rsendchar(TELOPT_ECHO, p);
+	if (send_iac_cmd(p, WONT, TELOPT_ECHO) < 0)
+		return -1;
 	p->tn_echo = 0;
+	return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static inline int send_iac_iac(ax25io *p)
+{
+	char buf[2] = { IAC, IAC };
+
+	return rsend(buf, 2, p);
+}
+
+static inline int send_iac_cmd(ax25io *p, char cmd, char opt)
+{
+	char buf[3];
+
+	buf[0] = IAC;
+	buf[1] = cmd;
+	buf[2] = opt;
+
+	return rsend(buf, 3, p);
+}
+
+static inline int send_linemode(ax25io *p)
+{
+	char buf[7] = { IAC, SB, TELOPT_LINEMODE, LM_MODE, MODE_EDIT | MODE_TRAPSIG, IAC, SE };
+
+	return rsend(buf, 7, p);
 }
 
 /* --------------------------------------------------------------------- */
 
+
diff -ru libax25-0.0.10.orig/ax25io.h libax25-0.0.10/ax25io.h
--- libax25-0.0.10.orig/ax25io.h	Tue Apr 10 04:54:09 2001
+++ libax25-0.0.10/ax25io.h	Tue Oct 15 22:41:33 2002
@@ -78,8 +78,8 @@
 
 extern int axio_printf(ax25io *, const char *, ...);
 
-extern void axio_tn_do_linemode(ax25io *);
-extern void axio_tn_will_echo(ax25io *);
-extern void axio_tn_wont_echo(ax25io *);
+extern int axio_tn_do_linemode(ax25io *);
+extern int axio_tn_will_echo(ax25io *);
+extern int axio_tn_wont_echo(ax25io *);
 
-#endif _AX25IO_H
+#endif		/* _AX25IO_H */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-18 22:37         ` Tomi Manninen
@ 2003-02-21 10:37           ` Craig Small
  2003-02-21 14:35             ` Tomi Manninen
  2003-02-21 15:53             ` Jeroen Vreeken
  0 siblings, 2 replies; 13+ messages in thread
From: Craig Small @ 2003-02-21 10:37 UTC (permalink / raw)
  To: Tomi Manninen; +Cc: Jeroen Vreeken, csmall, linux-hams

On Wed, Feb 19, 2003 at 12:37:03AM +0200, Tomi Manninen wrote:
> On Tue, 18 Feb 2003, Jeroen Vreeken wrote:
> 
> > Attached the same patch against what should have been in the CVS :)
> > 
> > btw getline changed a bit, the buffer is no longer global but in the ax25io
> > structure so each connection has its own (this is not a problem yet, but
> > might become one...)
> 
> Ok, after a very quick look this looks FB. And just in case Craig
> misplaced the earlier patch I was talking about, I added it here. So first
> my patch, then Jeroen's.

Great,  I've added both patches to the CVS.  You mention some programs
will break, what programs are they?

I'd like to release this library just with this patch but those programs
need fixing first, or at least the maintainers to be ready.

  - Craig
-- 
Craig Small VK2XLZ  GnuPG:1C1B D893 1418 2AF4 45EE  95CB C76C E5AC 12CA DFA5
Eye-Net Consulting http://www.enc.com.au/                <csmall@enc.com.au>
MIEEE <csmall@ieee.org>                 Debian developer <csmall@debian.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-21 10:37           ` Craig Small
@ 2003-02-21 14:35             ` Tomi Manninen
  2003-02-21 15:53             ` Jeroen Vreeken
  1 sibling, 0 replies; 13+ messages in thread
From: Tomi Manninen @ 2003-02-21 14:35 UTC (permalink / raw)
  To: Craig Small; +Cc: Jeroen Vreeken, linux-hams

On Fri, 21 Feb 2003, Craig Small wrote:

> > Ok, after a very quick look this looks FB. And just in case Craig
> > misplaced the earlier patch I was talking about, I added it here. So first
> > my patch, then Jeroen's.
> 
> Great,  I've added both patches to the CVS.  You mention some programs
> will break, what programs are they?

As far as I know the only program that really uses libax25io is node.  

Things have always been "broken" with node, at least up till
libax25-0.0.9. The fix in libax25-0.0.10 was wrong and buggy (wrong
approach, caused another just as bad problem). This patch is more or less
going back to the 0.0.9 behaviour but with a few relatively minor (but
important) problems fixed.

> I'd like to release this library just with this patch but those programs
> need fixing first, or at least the maintainers to be ready.

The original "brokenness" needs to be fixed in the applications using 
libax25io, like node. I have been working on this with help from Jeroen. I 
hope to be able to release a new node version soon.

If someone knows any other programs using libax25io, now would be a good 
time to let us know!

-- 
Tomi Manninen           Internet:  oh2bns@sral.fi
OH2BNS                  AX.25:     oh2bns@oh2rbi.fin.eu
KP20ME04                Amprnet:   oh2bns@oh2rbi.ampr.org


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-21 10:37           ` Craig Small
  2003-02-21 14:35             ` Tomi Manninen
@ 2003-02-21 15:53             ` Jeroen Vreeken
  2003-02-22 11:09               ` Craig Small
  1 sibling, 1 reply; 13+ messages in thread
From: Jeroen Vreeken @ 2003-02-21 15:53 UTC (permalink / raw)
  To: Craig Small; +Cc: Linux Hams, Tomi Manninen

On 2003.02.21 11:37:51 +0100 Craig Small wrote:

> Great,  I've added both patches to the CVS.  You mention some programs
> will break, what programs are they?
> 
> I'd like to release this library just with this patch but those programs
> need fixing first, or at least the maintainers to be ready.

As far as I know only a few node programs use it.
Fore node a patch is in the making so that won't be a show stopper.
I believe there are a few node forks (flexnode, awznode) that will probably
need fixing, but I think they can use the patch for node once its out.

	Jeroen


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] node and libax25io nonblocking
  2003-02-21 15:53             ` Jeroen Vreeken
@ 2003-02-22 11:09               ` Craig Small
  2003-02-25 15:57                 ` FBB and ax25 Tim Neu
  0 siblings, 1 reply; 13+ messages in thread
From: Craig Small @ 2003-02-22 11:09 UTC (permalink / raw)
  To: Jeroen Vreeken; +Cc: Linux Hams, Tomi Manninen

On Fri, Feb 21, 2003 at 04:53:37PM +0100, Jeroen Vreeken wrote:
> As far as I know only a few node programs use it.
> Fore node a patch is in the making so that won't be a show stopper.
> I believe there are a few node forks (flexnode, awznode) that will probably
> need fixing, but I think they can use the patch for node once its out.

Great, I'll leave it a week, very early March release the new library
to fix that brokeness.

  - Craig

-- 
Craig Small VK2XLZ  GnuPG:1C1B D893 1418 2AF4 45EE  95CB C76C E5AC 12CA DFA5
Eye-Net Consulting http://www.enc.com.au/                <csmall@enc.com.au>
MIEEE <csmall@ieee.org>                 Debian developer <csmall@debian.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* FBB and ax25
  2003-02-22 11:09               ` Craig Small
@ 2003-02-25 15:57                 ` Tim Neu
  2003-03-15 11:24                   ` Arno Verhoeven
  0 siblings, 1 reply; 13+ messages in thread
From: Tim Neu @ 2003-02-25 15:57 UTC (permalink / raw)
  To: Linux Hams

I have set up FBB on my linux box, listening at KC0LQL-3, and have NODE
also running on KC0LQL-5.     I use FBB for mail and conference, and
NODE for a database gateway (amoung other things). 

I want to be able to access either from a command prompt on the system,
however currently I can only get to "node" via "telnet localhost node".

I would like to be able to get to FBB the same way, but it does not
appear to have the same archietecture. (it runs as a daemon rather than
using ax25d.conf, and I do not see any listening TCP/IP ports).  How can
I get to FBB directly? Getting to it is possibe by using "call" to
digipeat to my host via a local digipeater, but that is a needless waste
of bandwidth. 

Finally, if I do digi through somewhere else and try to connect, my
connection is failing if there is already someone connected.  i.e. only
one person appears to be allowed on at a time.  I think I have something
set up incorrectly to prevent FBB from allowing multiple connections. 

I want to be able to have more than one connection active at a time (for
"conference" mode, and trivialnetdb access at least). 

Another alternative would be to ditch FBB in favor of some other
conference & email program. 

Any advice will be appreciated. 

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
______         _ __                          Military Intelligence
  /           ' )  )        -KC0LQL-         Honest Politician
 / o ______    /  / _  . .                   Intellectual Property  
/ <_/ / / <   /  (_</_(_/_  -- tneu@visi.com / http://www.visi.com/~tneu --

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: FBB and ax25
  2003-02-25 15:57                 ` FBB and ax25 Tim Neu
@ 2003-03-15 11:24                   ` Arno Verhoeven
  0 siblings, 0 replies; 13+ messages in thread
From: Arno Verhoeven @ 2003-03-15 11:24 UTC (permalink / raw)
  To: Tim Neu; +Cc: Linux Hams

Tim Neu wrote:

>I have set up FBB on my linux box, listening at KC0LQL-3, and have NODE
>also running on KC0LQL-5.     I use FBB for mail and conference, and
>NODE for a database gateway (amoung other things). 
>
>I want to be able to access either from a command prompt on the system,
>however currently I can only get to "node" via "telnet localhost node".
>
>I would like to be able to get to FBB the same way, but it does not
>appear to have the same archietecture. (it runs as a daemon rather than
>using ax25d.conf, and I do not see any listening TCP/IP ports).  How can
>I get to FBB directly? Getting to it is possibe by using "call" to
>digipeat to my host via a local digipeater, but that is a needless waste
>of bandwidth. 
>
There are several ways of getting into fbb from the command line. Sine 
you can already get into node from the command line, then one way of 
getting into fbb is via node.
You could simply connect to  KC0LQL-3 from node.
To do this your machine must listen to 2 netrom callsigns. (both  
KC0LQL-3 and KC0LQL-5)
Let me know if you need more details.

>
>Finally, if I do digi through somewhere else and try to connect, my
>connection is failing if there is already someone connected.  i.e. only
>one person appears to be allowed on at a time.  I think I have something
>set up incorrectly to prevent FBB from allowing multiple connections. 
>
>  
>
This is a setting in  FBB's port.sys file.
This is what I have at the end of that file.

#TNC NbCh Com MultCh Pacln Maxfr NbFwd MxBloc M/P-Fwd Mode Freq
0    0    0    0      0     0     0     0      00/01   ----  File-fwd.
1    15   1   netrom  230   4     5     30     05/60   UXY  netrom
2    5    2   0       250   2     2     10     00/60   TUW  Telnet
3    5    3   0       250   7     2     10     10/60   SU   Pop3

This allows 15 connections on the netrom port, 5 connections via telnet, 
and 5 simultaneous pop3 connections.

-- 
73, PE1ICQ  Arno Verhoeven
--------------------------------
AX.25  pe1icq@pi8zaa.#nbo.nld.eu
smtp   pe1icq@pi8zaa.ampr.org
inet   pe1icq@amsat.org 



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2003-03-15 11:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-02-17 20:56 [PATCH] node and libax25io nonblocking Jeroen Vreeken
2003-02-17 21:21 ` Tomi Manninen
2003-02-17 22:13 ` Tomi Manninen
2003-02-17 23:14   ` Jeroen Vreeken
2003-02-17 23:17     ` Tomi Manninen
2003-02-18 22:35       ` Jeroen Vreeken
2003-02-18 22:37         ` Tomi Manninen
2003-02-21 10:37           ` Craig Small
2003-02-21 14:35             ` Tomi Manninen
2003-02-21 15:53             ` Jeroen Vreeken
2003-02-22 11:09               ` Craig Small
2003-02-25 15:57                 ` FBB and ax25 Tim Neu
2003-03-15 11:24                   ` Arno Verhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox