summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Litwack <plitwack@mit.edu>2000-07-21 23:35:12 +0000
committerPeter Litwack <plitwack@mit.edu>2000-07-21 23:35:12 +0000
commit2dde150bac6865d4bbad7f9f443dcf3ed615c71e (patch)
treea32fa75588e74f515ea13c76b04a6c82555bae86 /src
parentb1bd7aa4c32ebb43315dbd3cd6565b14e4eee075 (diff)
downloadkrb5-2dde150bac6865d4bbad7f9f443dcf3ed615c71e.tar.gz
krb5-2dde150bac6865d4bbad7f9f443dcf3ed615c71e.tar.xz
krb5-2dde150bac6865d4bbad7f9f443dcf3ed615c71e.zip
* krlogin.c (writer): Improved bandwith efficiency by reading
and sending more than one character at a time if multiple characters are available to be read from the terminal. * krlogin.c (read_wrapper): Added this function as a helper to writer. It facilitates checking for escape sequences (~^Z etc.) when reading mulitple characters at a time. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12581 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/appl/bsd/ChangeLog9
-rw-r--r--src/appl/bsd/krlogin.c221
2 files changed, 162 insertions, 68 deletions
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index ed9da4367..4a1fdab64 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -1,3 +1,12 @@
+2000-07-21 Peter S Litwack <plitwack@mit.edu>
+
+ * krlogin.c (writer): Improved bandwith efficiency by reading
+ and sending more than one character at a time if multiple
+ characters are available to be read from the terminal.
+ * krlogin.c (read_wrapper): Added this function as a helper
+ to writer. It facilitates checking for escape sequences
+ (~^Z etc.) when reading mulitple characters at a time.
+
2000-07-18 Ezra Peisach <epeisach@mit.edu>
* krcp.c: Provide format attribute for error() for versions of gcc
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
index 0039056c3..d7ec552e9 100644
--- a/src/appl/bsd/krlogin.c
+++ b/src/appl/bsd/krlogin.c
@@ -379,7 +379,7 @@ main(argc, argv)
#endif
int port, debug_port = 0;
enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
+
memset(&defaultservent, 0, sizeof(struct servent));
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
@@ -1054,13 +1054,15 @@ int signo;
*/
writer()
{
- unsigned char c;
- register n;
- register bol = 1; /* beginning of line */
- register local = 0;
-
+ int n_read;
+ char buf[1024];
+ int got_esc; /* set to true by read_wrapper if an escape char
+ was encountered */
+ char c;
+
#ifdef ultrix
fd_set waitread;
+ register n;
/* we need to wait until the reader() has set up the terminal, else
the read() below may block and not unblock when the terminal
@@ -1081,90 +1083,173 @@ writer()
}
}
#endif /* ultrix */
+
+ /* This loop works as follows. Call read_wrapper to get data until
+ we would block or until we read a cmdchar at the beginning of a line.
+ If got_esc is false, we just send everything we got back. If got_esc
+ is true, we send everything except the cmdchar at the end and look at
+ the next char. If its a "." we break out of the loop and terminate.
+ If its ^Z or ^Y we call stop with the value of the char and continue.
+ If its none of those, we send the cmdchar and then send the char we
+ just read, unless that char is also the cmdchar (in which case we are
+ only supposed to send one of them). When this loop ends, so does the
+ program.
+ */
+
for (;;) {
- n = read(0, &c, 1);
- if (n <= 0) {
- if (n < 0 && errno == EINTR)
- continue;
+
+ /* read until we would block or we get a cmdchar */
+ n_read = read_wrapper(0,buf,sizeof(buf),&got_esc);
+
+ /* if read returns an error or 0 bytes, just quit */
+ if (n_read <= 0) {
+ break;
+ }
+
+ if (!got_esc) {
+ if (rcmd_stream_write(rem, buf, n_read, 0) == 0) {
+ prf("line gone");
+ break;
+ }
+ continue;
+ }
+ else {
+ /* This next test is necessary to avoid sending 0 bytes of data
+ in the event that we got just a cmdchar */
+ if (n_read > 1) {
+ if (rcmd_stream_write(rem, buf, n_read-1, 0) == 0) {
+ prf("line gone");
break;
+ }
}
- /*
- * If we're at the beginning of the line
- * and recognize a command character, then
- * we echo locally. Otherwise, characters
- * are echo'd remotely. If the command
- * character is doubled, this acts as a
- * force and local echo is suppressed.
- */
- if (bol) {
- bol = 0;
- if (c == cmdchar) {
- bol = 0;
- local = 1;
- continue;
- }
- } else if (local) {
- local = 0;
+ if (read_wrapper(0,&c,1,&got_esc) <= 0) {
+ break;
+ }
+
#ifdef POSIX_TERMIOS
- if (c == '.' || c == deftty.c_cc[VEOF]) {
+ if (c == '.' || c == deftty.c_cc[VEOF])
#else
- if (c == '.' || c == deftc.t_eofc) {
+ if (c == '.' || c == deftc.t_eofc)
#endif
- if (confirm_death()) {
- echo(c);
- break;
- }
- }
-#ifdef TIOCGLTC
- if ((c == defltc.t_suspc || c == defltc.t_dsuspc)
- && !no_local_escape) {
- bol = 1;
+ {
+ if (confirm_death()) {
echo(c);
- stop(c);
- continue;
+ break;
+ }
}
+
+#ifdef TIOCGLTC
+ if ((c == defltc.t_suspc || c == defltc.t_dsuspc)
+ && !no_local_escape) {
+ echo(c);
+ stop(c);
+ continue;
+ }
#else
#ifdef POSIX_TERMIOS
- if ( (
- (c == deftty.c_cc[VSUSP])
+ if ( (
+ (c == deftty.c_cc[VSUSP])
#ifdef VDSUSP
- || (c == deftty.c_cc[VDSUSP])
+ || (c == deftty.c_cc[VDSUSP])
#endif
- )
- && !no_local_escape) {
- bol = 1;
- echo(c);
- stop(c);
- continue;
- }
+ )
+ && !no_local_escape) {
+ echo(c);
+ stop(c);
+ continue;
+ }
#endif
#endif
-
- if (c != cmdchar)
- (void) rcmd_stream_write(rem, &cmdchar, 1, 0);
+
+ if (c != cmdchar) {
+ rcmd_stream_write(rem, &cmdchar, 1, 0);
}
- if (rcmd_stream_write(rem, &c, 1, 0) == 0) {
- prf("line gone");
- break;
+
+ if (rcmd_stream_write(rem,&c,1,0) == 0) {
+ prf("line gone");
+ break;
}
+ }
+ }
+}
+
+/* This function reads up to size bytes from file desciptor fd into buf.
+ It will copy as much data as it can without blocking, but will never
+ copy more than size bytes. In addition, if it encounters a cmdchar
+ at the beginning of a line, it will copy everything up to and including
+ the cmdchar, but nothing after that. In this instance *esc_char is set
+ to true and any remaining data is buffered and copied on a subsequent
+ call. Otherwise, *esc_char will be set to false and the minimum of size,
+ 1024, and the number of bytes that can be read without blocking will
+ be copied. In all cases, a non-negative return value indicates the number
+ of bytes actually copied and a return value of -1 indicates that there
+ was a read error (other than EINTR) and errno is set appropriately.
+*/
+
+int read_wrapper(fd,buf,size,got_esc)
+ int fd;
+ char *buf;
+ int size;
+ int *got_esc;
+{
+ static char tbuf[1024];
+ static char *data_start = tbuf;
+ static char *data_end = tbuf;
+ static int bol = 1;
+ int return_length = 0;
+ char c;
+
+ /* if we have no data buffered, get more */
+ if (data_start == data_end) {
+ int n_read;
+ while ((n_read = read(fd, tbuf, sizeof(tbuf))) <= 0) {
+ if (n_read < 0 && errno == EINTR)
+ continue;
+ return n_read;
+ }
+ data_start = tbuf;
+ data_end = tbuf+n_read;
+ }
+
+ *got_esc = 0;
+
+ /* We stop when we've fully checked the buffer or have checked size
+ bytes. We break out and set *got_esc if we encounter a cmdchar
+ at the beginning of a line.
+ */
+
+ while (data_start+return_length < data_end && return_length < size) {
+
+ c = *(data_start+return_length);
+ return_length++;
+
+ if (bol == 1 && c == cmdchar) {
+ bol = 0;
+ *got_esc = 1;
+ break;
+ }
+
#ifdef POSIX_TERMIOS
- bol = (c == deftty.c_cc[VKILL] ||
- c == deftty.c_cc[VINTR] ||
- c == '\r' || c == '\n');
+ bol = (c == deftty.c_cc[VKILL] ||
+ c == deftty.c_cc[VINTR] ||
+ c == '\r' || c == '\n');
#ifdef TIOCGLTC
- if (!bol)
- bol = (c == defltc.t_suspc);
+ if (!bol)
+ bol = (c == defltc.t_suspc);
#endif
-#else /* !POSIX_TERMIOS */
- bol = c == defkill || c == deftc.t_eofc ||
- c == deftc.t_intrc || c == defltc.t_suspc ||
- c == '\r' || c == '\n';
+
+#else / * !POSIX_TERMIOS * /
+ bol = c == defkill || c == deftc.t_eofc ||
+ c == deftc.t_intrc || c == defltc.t_suspc ||
+ c == '\r' || c == '\n';
#endif
- }
+ }
+
+ memcpy(buf,tbuf, return_length);
+ data_start = data_start + return_length;
+ return return_length;
}
-
-
echo(c)
register char c;
{