From 78b0e379d7c2db84eec34ccd89cf9afb67b94901 Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Tue, 26 Jun 2001 02:06:08 +0000 Subject: [PATCH] Vladimir's last_patch_15 --- Makefile | 2 +- cmdedit.c | 92 ++++++++++++++++++++---------------- editors/vi.c | 4 +- hostname.c | 7 +-- hush.c | 2 +- include/libbb.h | 6 ++- libbb/libbb.h | 6 ++- more.c | 106 +++++++++++++++++++++--------------------- networking/hostname.c | 7 +-- networking/telnet.c | 46 +++++++++--------- shell/cmdedit.c | 92 ++++++++++++++++++++---------------- shell/hush.c | 2 +- telnet.c | 46 +++++++++--------- util-linux/more.c | 106 +++++++++++++++++++++--------------------- vi.c | 4 +- 15 files changed, 275 insertions(+), 253 deletions(-) diff --git a/Makefile b/Makefile index 0474d17e3..0e5086ddf 100644 --- a/Makefile +++ b/Makefile @@ -249,7 +249,7 @@ safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \ trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \ xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \ copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \ -dirname.c make_directory.c strdup_substr.c +dirname.c make_directory.c LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) LIBBB_CFLAGS = -I$(LIBBB) ifneq ($(strip $(BB_SRC_DIR)),) diff --git a/cmdedit.c b/cmdedit.c index a2b238603..981253db1 100644 --- a/cmdedit.c +++ b/cmdedit.c @@ -81,11 +81,11 @@ #endif #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR -#ifndef TEST -#include "pwd_grp/pwd.h" -#else -#include -#endif /* TEST */ +# ifndef TEST +# include "pwd_grp/pwd.h" +# else +# include +# endif /* TEST */ #endif /* advanced FEATURES */ @@ -106,28 +106,14 @@ static struct history *his_front = NULL; static struct history *his_end = NULL; -/* ED: sparc termios is broken: revert back to old termio handling. */ - -#if #cpu(sparc) -# include -# define termios termio -# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp) -# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp) -#else -# include -# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) -# define getTermSettings(fd,argp) tcgetattr(fd, argp); -#endif +#include +#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) +#define getTermSettings(fd,argp) tcgetattr(fd, argp); /* Current termio and the previous termio before starting sh */ static struct termios initial_settings, new_settings; -#ifndef _POSIX_VDISABLE -#define _POSIX_VDISABLE '\0' -#endif - - static volatile int cmdedit_termw = 80; /* actual terminal width */ static int history_counter = 0; /* Number of commands in history list */ @@ -356,7 +342,7 @@ static void parse_prompt(const char *prmt_ptr) char *pbuf; if (!pwd_buf) { - pwd_buf=unknown; + pwd_buf=(char *)unknown; } while (*prmt_ptr) { @@ -1041,9 +1027,30 @@ static void input_tab(int *lastWasTab) * in the current working directory that matches. */ if (!matches) matches = - exe_n_cwd_tab_completion(matchBuf, &num_matches, - find_type); - + exe_n_cwd_tab_completion(matchBuf, + &num_matches, find_type); + /* Remove duplicate found */ + if(matches) { + int i, j; + /* bubble */ + for(i=0; i<(num_matches-1); i++) + for(j=i+1; j 1) { char *tmp1; @@ -1169,8 +1176,6 @@ enum { extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) { - int inputFd = fileno(stdin); - int break_out = 0; int lastWasTab = FALSE; unsigned char c = 0; @@ -1181,23 +1186,28 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) len = 0; command_ps = command; - if (new_settings.c_cc[VMIN] == 0) { /* first call */ + if (new_settings.c_cc[VERASE] == 0) { /* first call */ - getTermSettings(inputFd, (void *) &initial_settings); + getTermSettings(0, (void *) &initial_settings); memcpy(&new_settings, &initial_settings, sizeof(struct termios)); - + new_settings.c_lflag &= ~ICANON; /* unbuffered input */ + /* Turn off echoing and CTRL-C, so we can trap it */ + new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); +#ifndef linux + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; /* Turn off CTRL-C, so we can trap it */ +# ifndef _POSIX_VDISABLE +# define _POSIX_VDISABLE '\0' +# endif new_settings.c_cc[VINTR] = _POSIX_VDISABLE; - new_settings.c_lflag &= ~ICANON; /* unbuffered input */ - /* Turn off echoing */ - new_settings.c_lflag &= ~(ECHO | ECHOCTL | ECHONL); +#endif } command[0] = 0; - setTermSettings(inputFd, (void *) &new_settings); + setTermSettings(0, (void *) &new_settings); handlers_sets |= SET_RESET_TERM; /* Now initialize things */ @@ -1209,7 +1219,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) fflush(stdout); /* buffered out to fast */ - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) /* if we can't read input then exit */ goto prepare_to_die; @@ -1296,11 +1306,11 @@ prepare_to_die: case ESC:{ /* escape sequence follows */ - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; /* different vt100 emulations */ if (c == '[' || c == 'O') { - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; } switch (c) { @@ -1365,7 +1375,7 @@ prepare_to_die: } if (c >= '1' && c <= '9') do - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; while (c != '~'); break; @@ -1375,7 +1385,7 @@ prepare_to_die: #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT /* Control-V -- Add non-printable symbol */ if (c == 22) { - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; if (c == 0) { beep(); @@ -1416,7 +1426,7 @@ prepare_to_die: lastWasTab = FALSE; } - setTermSettings(inputFd, (void *) &initial_settings); + setTermSettings(0, (void *) &initial_settings); handlers_sets &= ~SET_RESET_TERM; /* Handle command history log */ diff --git a/editors/vi.c b/editors/vi.c index bd183e8b0..e1ff9336f 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -19,7 +19,7 @@ */ char *vi_Version = - "$Id: vi.c,v 1.9 2001/06/23 13:49:14 andersen Exp $"; + "$Id: vi.c,v 1.10 2001/06/26 02:06:08 bug1 Exp $"; /* * To compile for standalone use: @@ -3152,8 +3152,10 @@ static void rawmode(void) term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's term_vi.c_iflag &= (~IXON & ~ICRNL); term_vi.c_oflag &= (~ONLCR); +#ifndef linux term_vi.c_cc[VMIN] = 1; term_vi.c_cc[VTIME] = 0; +#endif erase_char = term_vi.c_cc[VERASE]; tcsetattr(0, TCSANOW, &term_vi); } diff --git a/hostname.c b/hostname.c index 573c8cece..d87851509 100644 --- a/hostname.c +++ b/hostname.c @@ -1,6 +1,6 @@ /* vi: set sw=4 ts=4: */ /* - * $Id: hostname.c,v 1.29 2001/06/23 13:49:14 andersen Exp $ + * $Id: hostname.c,v 1.30 2001/06/26 02:06:08 bug1 Exp $ * Mini hostname implementation for busybox * * Copyright (C) 1999 by Randolph Chung @@ -49,10 +49,11 @@ static void do_sethostname(char *s, int isfile) } else { f = xfopen(s, "r"); fgets(buf, 255, f); +#ifdef BB_FEATURE_CLEAN_UP fclose(f); +#endif chomp(buf); - if (sethostname(buf, strlen(buf)) < 0) - perror_msg_and_die("sethostname"); + do_sethostname(buf, 0); } } diff --git a/hush.c b/hush.c index b0637f806..859353dcf 100644 --- a/hush.c +++ b/hush.c @@ -861,7 +861,7 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str) *prompt_str = PS2; } #else - *prompt_str = (promptmode==0)? PS1 : PS2; + *prompt_str = (promptmode==1)? PS1 : PS2; #endif debug_printf("result %s\n",*prompt_str); } diff --git a/include/libbb.h b/include/libbb.h index 102596c1f..3b0ced7d1 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -243,7 +243,11 @@ extern FILE *gz_open(FILE *compressed_file, int *pid); extern struct hostent *xgethostbyname(const char *name); char *dirname (const char *path); -char *strdup_substr (const char *s, int start, int end); + +static inline char *strdup_substr (const char *s, int start, int end) +{ + return xstrndup (s+start, end-start); +} int make_directory (char *path, mode_t mode, int flags); #define CT_AUTO 0 diff --git a/libbb/libbb.h b/libbb/libbb.h index 102596c1f..3b0ced7d1 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -243,7 +243,11 @@ extern FILE *gz_open(FILE *compressed_file, int *pid); extern struct hostent *xgethostbyname(const char *name); char *dirname (const char *path); -char *strdup_substr (const char *s, int start, int end); + +static inline char *strdup_substr (const char *s, int start, int end) +{ + return xstrndup (s+start, end-start); +} int make_directory (char *path, mode_t mode, int flags); #define CT_AUTO 0 diff --git a/more.c b/more.c index 9f07633c3..6cdec729b 100644 --- a/more.c +++ b/more.c @@ -9,6 +9,8 @@ * based on the original more implementation by Bruce, and code from the * Debian boot-floppies team. * + * Termios corrects by Vladimir Oleynik + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -29,29 +31,26 @@ #include #include #include +#include #include #include "busybox.h" -/* ED: sparc termios is broken: revert back to old termio handling. */ -#ifdef BB_FEATURE_USE_TERMIOS -# if #cpu(sparc) -# include -# define termios termio -# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp) -# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp) -# else -# include -# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) -# define getTermSettings(fd,argp) tcgetattr(fd, argp); -# endif - static FILE *cin; +#ifdef BB_FEATURE_USE_TERMIOS +#include +#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) +#define getTermSettings(fd,argp) tcgetattr(fd, argp); + static struct termios initial_settings, new_settings; -static void gotsig(int sig) +static void set_tty_to_initial_mode(void) { setTermSettings(fileno(cin), &initial_settings); +} + +static void gotsig(int sig) +{ putchar('\n'); exit(EXIT_FAILURE); } @@ -65,7 +64,7 @@ static int terminal_height = 24; extern int more_main(int argc, char **argv) { int c, lines, input = 0; - int please_display_more_prompt; + int please_display_more_prompt = -1; struct stat st; FILE *file; int len, page_height; @@ -77,46 +76,57 @@ extern int more_main(int argc, char **argv) argc--; argv++; + + /* not use inputing from terminal if usage: more > outfile */ + if(isatty(fileno(stdout))) { + cin = fopen("/dev/tty", "r"); + if (!cin) + cin = xfopen("/dev/console", "r"); + please_display_more_prompt = 0; +#ifdef BB_FEATURE_USE_TERMIOS + getTermSettings(fileno(cin), &initial_settings); + new_settings = initial_settings; + new_settings.c_lflag &= ~ICANON; + new_settings.c_lflag &= ~ECHO; +#ifndef linux + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; +#endif + setTermSettings(fileno(cin), &new_settings); + atexit(set_tty_to_initial_mode); + (void) signal(SIGINT, gotsig); + (void) signal(SIGQUIT, gotsig); + (void) signal(SIGTERM, gotsig); +#endif + } + do { if (argc == 0) { file = stdin; } else - file = xfopen(*argv, "r"); - + file = wfopen(*argv, "r"); + if(file==0) + goto loop; + fstat(fileno(file), &st); -#ifdef BB_FEATURE_USE_TERMIOS - cin = fopen("/dev/tty", "r"); - if (!cin) - cin = xfopen("/dev/console", "r"); - getTermSettings(fileno(cin), &initial_settings); - new_settings = initial_settings; - new_settings.c_cc[VMIN] = 1; - new_settings.c_cc[VTIME] = 0; - new_settings.c_lflag &= ~ICANON; - new_settings.c_lflag &= ~ECHO; - setTermSettings(fileno(cin), &new_settings); + if(please_display_more_prompt>0) + please_display_more_prompt = 0; -# ifdef BB_FEATURE_AUTOWIDTH +#if defined BB_FEATURE_AUTOWIDTH && defined BB_FEATURE_USE_TERMIOS ioctl(fileno(stdout), TIOCGWINSZ, &win); if (win.ws_row > 4) terminal_height = win.ws_row - 2; if (win.ws_col > 0) terminal_width = win.ws_col - 1; -# endif - - (void) signal(SIGINT, gotsig); - (void) signal(SIGQUIT, gotsig); - (void) signal(SIGTERM, gotsig); - #endif len=0; lines = 0; page_height = terminal_height; - please_display_more_prompt = 0; while ((c = getc(file)) != EOF) { - if (please_display_more_prompt) { + if (please_display_more_prompt>0) { len = printf("--More-- "); if (file != stdin) { #if _FILE_OFFSET_BITS == 64 @@ -129,13 +139,6 @@ extern int more_main(int argc, char **argv) (double) st.st_size)), (long)st.st_size); #endif } - len += printf("%s", -#ifdef BB_FEATURE_USE_TERMIOS - "" -#else - "\n" -#endif - ); fflush(stdout); @@ -143,20 +146,16 @@ extern int more_main(int argc, char **argv) * We've just displayed the "--More--" prompt, so now we need * to get input from the user. */ -#ifdef BB_FEATURE_USE_TERMIOS input = getc(cin); -#else - input = getc(stdin); +#ifndef BB_FEATURE_USE_TERMIOS + printf("\033[A"); /* up cursor */ #endif - -#ifdef BB_FEATURE_USE_TERMIOS /* Erase the "More" message */ putc('\r', stdout); while (--len >= 0) putc(' ', stdout); putc('\r', stdout); fflush(stdout); -#endif len=0; lines = 0; page_height = terminal_height; @@ -180,6 +179,7 @@ extern int more_main(int argc, char **argv) /* increment by just one line if we are at * the end of this line */ if (input == '\n') + if(please_display_more_prompt==0) please_display_more_prompt = 1; /* Adjust the terminal height for any overlap, so that * no lines get lost off the top. */ @@ -195,6 +195,7 @@ extern int more_main(int argc, char **argv) } } if (++lines >= page_height) { + if(please_display_more_prompt==0) please_display_more_prompt = 1; } len=0; @@ -208,12 +209,9 @@ extern int more_main(int argc, char **argv) } fclose(file); fflush(stdout); - +loop: argv++; } while (--argc > 0); end: -#ifdef BB_FEATURE_USE_TERMIOS - setTermSettings(fileno(cin), &initial_settings); -#endif return 0; } diff --git a/networking/hostname.c b/networking/hostname.c index 573c8cece..d87851509 100644 --- a/networking/hostname.c +++ b/networking/hostname.c @@ -1,6 +1,6 @@ /* vi: set sw=4 ts=4: */ /* - * $Id: hostname.c,v 1.29 2001/06/23 13:49:14 andersen Exp $ + * $Id: hostname.c,v 1.30 2001/06/26 02:06:08 bug1 Exp $ * Mini hostname implementation for busybox * * Copyright (C) 1999 by Randolph Chung @@ -49,10 +49,11 @@ static void do_sethostname(char *s, int isfile) } else { f = xfopen(s, "r"); fgets(buf, 255, f); +#ifdef BB_FEATURE_CLEAN_UP fclose(f); +#endif chomp(buf); - if (sethostname(buf, strlen(buf)) < 0) - perror_msg_and_die("sethostname"); + do_sethostname(buf, 0); } } diff --git a/networking/telnet.c b/networking/telnet.c index 2587193e2..ce82a0ee8 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -64,8 +64,8 @@ static const int DOTRACE = 1; #include #endif -static const int DATABUFSIZE = 128; -static const int IACBUFSIZE = 128; +#define DATABUFSIZE 128 +#define IACBUFSIZE 128 static const int CHM_TRY = 0; static const int CHM_ON = 1; @@ -90,15 +90,14 @@ typedef unsigned char byte; static struct Globalvars { int netfd; /* console fd:s are 0 and 1 (and 2) */ /* same buffer used both for network and console read/write */ - char * buf; /* allocating so static size is smaller */ - short len; + char buf[DATABUFSIZE]; /* allocating so static size is smaller */ byte telstate; /* telnet negotiation state from network input */ byte telwish; /* DO, DONT, WILL, WONT */ byte charmode; byte telflags; byte gotsig; /* buffer to handle telnet negotiations */ - char * iacbuf; + char iacbuf[IACBUFSIZE]; short iaclen; /* could even use byte */ struct termios termios_def; struct termios termios_raw; @@ -198,7 +197,7 @@ static void conescape() G.gotsig = 0; } -static void handlenetoutput() +static void handlenetoutput(int len) { /* here we could do smart tricks how to handle 0xFF:s in output * stream like writing twice every sequence of FF:s (thus doing @@ -209,7 +208,7 @@ static void handlenetoutput() int i; byte * p = G.buf; - for (i = G.len; i > 0; i--, p++) + for (i = len; i > 0; i--, p++) { if (*p == 0x1d) { @@ -219,16 +218,16 @@ static void handlenetoutput() if (*p == 0xff) *p = 0x7f; } - write(G.netfd, G.buf, G.len); + write(G.netfd, G.buf, len); } -static void handlenetinput() +static void handlenetinput(int len) { int i; int cstart = 0; - for (i = 0; i < G.len; i++) + for (i = 0; i < len; i++) { byte c = G.buf[i]; @@ -290,11 +289,11 @@ static void handlenetinput() if (G.iaclen) iacflush(); if (G.telstate == TS_0) G.telstate = 0; - G.len = cstart; + len = cstart; } - if (G.len) - write(1, G.buf, G.len); + if (len) + write(1, G.buf, len); } @@ -530,6 +529,7 @@ extern int telnet_main(int argc, char** argv) { struct in_addr host; int port; + int len; #ifdef USE_POLL struct pollfd ufds[2]; #else @@ -547,15 +547,11 @@ extern int telnet_main(int argc, char** argv) exit(1); G.termios_raw = G.termios_def; - cfmakeraw(&G.termios_raw); if (argc < 2) show_usage(); port = (argc > 2)? getport(argv[2]): 23; - G.buf = xmalloc(DATABUFSIZE); - G.iacbuf = xmalloc(IACBUFSIZE); - host = getserver(argv[1]); G.netfd = remote_connect(host, port); @@ -599,14 +595,14 @@ extern int telnet_main(int argc, char** argv) if (FD_ISSET(0, &rfds)) #endif { - G.len = read(0, G.buf, DATABUFSIZE); + len = read(0, G.buf, DATABUFSIZE); - if (G.len <= 0) + if (len <= 0) doexit(0); - TRACE(0, ("Read con: %d\n", G.len)); + TRACE(0, ("Read con: %d\n", len)); - handlenetoutput(); + handlenetoutput(len); } #ifdef USE_POLL @@ -615,16 +611,16 @@ extern int telnet_main(int argc, char** argv) if (FD_ISSET(G.netfd, &rfds)) #endif { - G.len = read(G.netfd, G.buf, DATABUFSIZE); + len = read(G.netfd, G.buf, DATABUFSIZE); - if (G.len <= 0) + if (len <= 0) { WriteCS(1, "Connection closed by foreign host.\r\n"); doexit(1); } - TRACE(0, ("Read netfd (%d): %d\n", G.netfd, G.len)); + TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); - handlenetinput(); + handlenetinput(len); } } } diff --git a/shell/cmdedit.c b/shell/cmdedit.c index a2b238603..981253db1 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -81,11 +81,11 @@ #endif #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR -#ifndef TEST -#include "pwd_grp/pwd.h" -#else -#include -#endif /* TEST */ +# ifndef TEST +# include "pwd_grp/pwd.h" +# else +# include +# endif /* TEST */ #endif /* advanced FEATURES */ @@ -106,28 +106,14 @@ static struct history *his_front = NULL; static struct history *his_end = NULL; -/* ED: sparc termios is broken: revert back to old termio handling. */ - -#if #cpu(sparc) -# include -# define termios termio -# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp) -# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp) -#else -# include -# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) -# define getTermSettings(fd,argp) tcgetattr(fd, argp); -#endif +#include +#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) +#define getTermSettings(fd,argp) tcgetattr(fd, argp); /* Current termio and the previous termio before starting sh */ static struct termios initial_settings, new_settings; -#ifndef _POSIX_VDISABLE -#define _POSIX_VDISABLE '\0' -#endif - - static volatile int cmdedit_termw = 80; /* actual terminal width */ static int history_counter = 0; /* Number of commands in history list */ @@ -356,7 +342,7 @@ static void parse_prompt(const char *prmt_ptr) char *pbuf; if (!pwd_buf) { - pwd_buf=unknown; + pwd_buf=(char *)unknown; } while (*prmt_ptr) { @@ -1041,9 +1027,30 @@ static void input_tab(int *lastWasTab) * in the current working directory that matches. */ if (!matches) matches = - exe_n_cwd_tab_completion(matchBuf, &num_matches, - find_type); - + exe_n_cwd_tab_completion(matchBuf, + &num_matches, find_type); + /* Remove duplicate found */ + if(matches) { + int i, j; + /* bubble */ + for(i=0; i<(num_matches-1); i++) + for(j=i+1; j 1) { char *tmp1; @@ -1169,8 +1176,6 @@ enum { extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) { - int inputFd = fileno(stdin); - int break_out = 0; int lastWasTab = FALSE; unsigned char c = 0; @@ -1181,23 +1186,28 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) len = 0; command_ps = command; - if (new_settings.c_cc[VMIN] == 0) { /* first call */ + if (new_settings.c_cc[VERASE] == 0) { /* first call */ - getTermSettings(inputFd, (void *) &initial_settings); + getTermSettings(0, (void *) &initial_settings); memcpy(&new_settings, &initial_settings, sizeof(struct termios)); - + new_settings.c_lflag &= ~ICANON; /* unbuffered input */ + /* Turn off echoing and CTRL-C, so we can trap it */ + new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); +#ifndef linux + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; /* Turn off CTRL-C, so we can trap it */ +# ifndef _POSIX_VDISABLE +# define _POSIX_VDISABLE '\0' +# endif new_settings.c_cc[VINTR] = _POSIX_VDISABLE; - new_settings.c_lflag &= ~ICANON; /* unbuffered input */ - /* Turn off echoing */ - new_settings.c_lflag &= ~(ECHO | ECHOCTL | ECHONL); +#endif } command[0] = 0; - setTermSettings(inputFd, (void *) &new_settings); + setTermSettings(0, (void *) &new_settings); handlers_sets |= SET_RESET_TERM; /* Now initialize things */ @@ -1209,7 +1219,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) fflush(stdout); /* buffered out to fast */ - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) /* if we can't read input then exit */ goto prepare_to_die; @@ -1296,11 +1306,11 @@ prepare_to_die: case ESC:{ /* escape sequence follows */ - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; /* different vt100 emulations */ if (c == '[' || c == 'O') { - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; } switch (c) { @@ -1365,7 +1375,7 @@ prepare_to_die: } if (c >= '1' && c <= '9') do - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; while (c != '~'); break; @@ -1375,7 +1385,7 @@ prepare_to_die: #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT /* Control-V -- Add non-printable symbol */ if (c == 22) { - if (read(inputFd, &c, 1) < 1) + if (read(0, &c, 1) < 1) return; if (c == 0) { beep(); @@ -1416,7 +1426,7 @@ prepare_to_die: lastWasTab = FALSE; } - setTermSettings(inputFd, (void *) &initial_settings); + setTermSettings(0, (void *) &initial_settings); handlers_sets &= ~SET_RESET_TERM; /* Handle command history log */ diff --git a/shell/hush.c b/shell/hush.c index b0637f806..859353dcf 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -861,7 +861,7 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str) *prompt_str = PS2; } #else - *prompt_str = (promptmode==0)? PS1 : PS2; + *prompt_str = (promptmode==1)? PS1 : PS2; #endif debug_printf("result %s\n",*prompt_str); } diff --git a/telnet.c b/telnet.c index 2587193e2..ce82a0ee8 100644 --- a/telnet.c +++ b/telnet.c @@ -64,8 +64,8 @@ static const int DOTRACE = 1; #include #endif -static const int DATABUFSIZE = 128; -static const int IACBUFSIZE = 128; +#define DATABUFSIZE 128 +#define IACBUFSIZE 128 static const int CHM_TRY = 0; static const int CHM_ON = 1; @@ -90,15 +90,14 @@ typedef unsigned char byte; static struct Globalvars { int netfd; /* console fd:s are 0 and 1 (and 2) */ /* same buffer used both for network and console read/write */ - char * buf; /* allocating so static size is smaller */ - short len; + char buf[DATABUFSIZE]; /* allocating so static size is smaller */ byte telstate; /* telnet negotiation state from network input */ byte telwish; /* DO, DONT, WILL, WONT */ byte charmode; byte telflags; byte gotsig; /* buffer to handle telnet negotiations */ - char * iacbuf; + char iacbuf[IACBUFSIZE]; short iaclen; /* could even use byte */ struct termios termios_def; struct termios termios_raw; @@ -198,7 +197,7 @@ static void conescape() G.gotsig = 0; } -static void handlenetoutput() +static void handlenetoutput(int len) { /* here we could do smart tricks how to handle 0xFF:s in output * stream like writing twice every sequence of FF:s (thus doing @@ -209,7 +208,7 @@ static void handlenetoutput() int i; byte * p = G.buf; - for (i = G.len; i > 0; i--, p++) + for (i = len; i > 0; i--, p++) { if (*p == 0x1d) { @@ -219,16 +218,16 @@ static void handlenetoutput() if (*p == 0xff) *p = 0x7f; } - write(G.netfd, G.buf, G.len); + write(G.netfd, G.buf, len); } -static void handlenetinput() +static void handlenetinput(int len) { int i; int cstart = 0; - for (i = 0; i < G.len; i++) + for (i = 0; i < len; i++) { byte c = G.buf[i]; @@ -290,11 +289,11 @@ static void handlenetinput() if (G.iaclen) iacflush(); if (G.telstate == TS_0) G.telstate = 0; - G.len = cstart; + len = cstart; } - if (G.len) - write(1, G.buf, G.len); + if (len) + write(1, G.buf, len); } @@ -530,6 +529,7 @@ extern int telnet_main(int argc, char** argv) { struct in_addr host; int port; + int len; #ifdef USE_POLL struct pollfd ufds[2]; #else @@ -547,15 +547,11 @@ extern int telnet_main(int argc, char** argv) exit(1); G.termios_raw = G.termios_def; - cfmakeraw(&G.termios_raw); if (argc < 2) show_usage(); port = (argc > 2)? getport(argv[2]): 23; - G.buf = xmalloc(DATABUFSIZE); - G.iacbuf = xmalloc(IACBUFSIZE); - host = getserver(argv[1]); G.netfd = remote_connect(host, port); @@ -599,14 +595,14 @@ extern int telnet_main(int argc, char** argv) if (FD_ISSET(0, &rfds)) #endif { - G.len = read(0, G.buf, DATABUFSIZE); + len = read(0, G.buf, DATABUFSIZE); - if (G.len <= 0) + if (len <= 0) doexit(0); - TRACE(0, ("Read con: %d\n", G.len)); + TRACE(0, ("Read con: %d\n", len)); - handlenetoutput(); + handlenetoutput(len); } #ifdef USE_POLL @@ -615,16 +611,16 @@ extern int telnet_main(int argc, char** argv) if (FD_ISSET(G.netfd, &rfds)) #endif { - G.len = read(G.netfd, G.buf, DATABUFSIZE); + len = read(G.netfd, G.buf, DATABUFSIZE); - if (G.len <= 0) + if (len <= 0) { WriteCS(1, "Connection closed by foreign host.\r\n"); doexit(1); } - TRACE(0, ("Read netfd (%d): %d\n", G.netfd, G.len)); + TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); - handlenetinput(); + handlenetinput(len); } } } diff --git a/util-linux/more.c b/util-linux/more.c index 9f07633c3..6cdec729b 100644 --- a/util-linux/more.c +++ b/util-linux/more.c @@ -9,6 +9,8 @@ * based on the original more implementation by Bruce, and code from the * Debian boot-floppies team. * + * Termios corrects by Vladimir Oleynik + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -29,29 +31,26 @@ #include #include #include +#include #include #include "busybox.h" -/* ED: sparc termios is broken: revert back to old termio handling. */ -#ifdef BB_FEATURE_USE_TERMIOS -# if #cpu(sparc) -# include -# define termios termio -# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp) -# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp) -# else -# include -# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) -# define getTermSettings(fd,argp) tcgetattr(fd, argp); -# endif - static FILE *cin; +#ifdef BB_FEATURE_USE_TERMIOS +#include +#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) +#define getTermSettings(fd,argp) tcgetattr(fd, argp); + static struct termios initial_settings, new_settings; -static void gotsig(int sig) +static void set_tty_to_initial_mode(void) { setTermSettings(fileno(cin), &initial_settings); +} + +static void gotsig(int sig) +{ putchar('\n'); exit(EXIT_FAILURE); } @@ -65,7 +64,7 @@ static int terminal_height = 24; extern int more_main(int argc, char **argv) { int c, lines, input = 0; - int please_display_more_prompt; + int please_display_more_prompt = -1; struct stat st; FILE *file; int len, page_height; @@ -77,46 +76,57 @@ extern int more_main(int argc, char **argv) argc--; argv++; + + /* not use inputing from terminal if usage: more > outfile */ + if(isatty(fileno(stdout))) { + cin = fopen("/dev/tty", "r"); + if (!cin) + cin = xfopen("/dev/console", "r"); + please_display_more_prompt = 0; +#ifdef BB_FEATURE_USE_TERMIOS + getTermSettings(fileno(cin), &initial_settings); + new_settings = initial_settings; + new_settings.c_lflag &= ~ICANON; + new_settings.c_lflag &= ~ECHO; +#ifndef linux + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; +#endif + setTermSettings(fileno(cin), &new_settings); + atexit(set_tty_to_initial_mode); + (void) signal(SIGINT, gotsig); + (void) signal(SIGQUIT, gotsig); + (void) signal(SIGTERM, gotsig); +#endif + } + do { if (argc == 0) { file = stdin; } else - file = xfopen(*argv, "r"); - + file = wfopen(*argv, "r"); + if(file==0) + goto loop; + fstat(fileno(file), &st); -#ifdef BB_FEATURE_USE_TERMIOS - cin = fopen("/dev/tty", "r"); - if (!cin) - cin = xfopen("/dev/console", "r"); - getTermSettings(fileno(cin), &initial_settings); - new_settings = initial_settings; - new_settings.c_cc[VMIN] = 1; - new_settings.c_cc[VTIME] = 0; - new_settings.c_lflag &= ~ICANON; - new_settings.c_lflag &= ~ECHO; - setTermSettings(fileno(cin), &new_settings); + if(please_display_more_prompt>0) + please_display_more_prompt = 0; -# ifdef BB_FEATURE_AUTOWIDTH +#if defined BB_FEATURE_AUTOWIDTH && defined BB_FEATURE_USE_TERMIOS ioctl(fileno(stdout), TIOCGWINSZ, &win); if (win.ws_row > 4) terminal_height = win.ws_row - 2; if (win.ws_col > 0) terminal_width = win.ws_col - 1; -# endif - - (void) signal(SIGINT, gotsig); - (void) signal(SIGQUIT, gotsig); - (void) signal(SIGTERM, gotsig); - #endif len=0; lines = 0; page_height = terminal_height; - please_display_more_prompt = 0; while ((c = getc(file)) != EOF) { - if (please_display_more_prompt) { + if (please_display_more_prompt>0) { len = printf("--More-- "); if (file != stdin) { #if _FILE_OFFSET_BITS == 64 @@ -129,13 +139,6 @@ extern int more_main(int argc, char **argv) (double) st.st_size)), (long)st.st_size); #endif } - len += printf("%s", -#ifdef BB_FEATURE_USE_TERMIOS - "" -#else - "\n" -#endif - ); fflush(stdout); @@ -143,20 +146,16 @@ extern int more_main(int argc, char **argv) * We've just displayed the "--More--" prompt, so now we need * to get input from the user. */ -#ifdef BB_FEATURE_USE_TERMIOS input = getc(cin); -#else - input = getc(stdin); +#ifndef BB_FEATURE_USE_TERMIOS + printf("\033[A"); /* up cursor */ #endif - -#ifdef BB_FEATURE_USE_TERMIOS /* Erase the "More" message */ putc('\r', stdout); while (--len >= 0) putc(' ', stdout); putc('\r', stdout); fflush(stdout); -#endif len=0; lines = 0; page_height = terminal_height; @@ -180,6 +179,7 @@ extern int more_main(int argc, char **argv) /* increment by just one line if we are at * the end of this line */ if (input == '\n') + if(please_display_more_prompt==0) please_display_more_prompt = 1; /* Adjust the terminal height for any overlap, so that * no lines get lost off the top. */ @@ -195,6 +195,7 @@ extern int more_main(int argc, char **argv) } } if (++lines >= page_height) { + if(please_display_more_prompt==0) please_display_more_prompt = 1; } len=0; @@ -208,12 +209,9 @@ extern int more_main(int argc, char **argv) } fclose(file); fflush(stdout); - +loop: argv++; } while (--argc > 0); end: -#ifdef BB_FEATURE_USE_TERMIOS - setTermSettings(fileno(cin), &initial_settings); -#endif return 0; } diff --git a/vi.c b/vi.c index bd183e8b0..e1ff9336f 100644 --- a/vi.c +++ b/vi.c @@ -19,7 +19,7 @@ */ char *vi_Version = - "$Id: vi.c,v 1.9 2001/06/23 13:49:14 andersen Exp $"; + "$Id: vi.c,v 1.10 2001/06/26 02:06:08 bug1 Exp $"; /* * To compile for standalone use: @@ -3152,8 +3152,10 @@ static void rawmode(void) term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's term_vi.c_iflag &= (~IXON & ~ICRNL); term_vi.c_oflag &= (~ONLCR); +#ifndef linux term_vi.c_cc[VMIN] = 1; term_vi.c_cc[VTIME] = 0; +#endif erase_char = term_vi.c_cc[VERASE]; tcsetattr(0, TCSANOW, &term_vi); }