summaryrefslogtreecommitdiffstats
path: root/bin/hpfilter.c
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2004-01-12 03:17:26 +0000
committerTar Committer <tar@ocjtech.us>2004-01-12 03:17:26 +0000
commit989312339ea2e16579803a48700628c5469e327a (patch)
tree967ee77195819d70f2dc675444e92340bb98e0d6 /bin/hpfilter.c
parentff168ecfe045c690c24d5bbc5a3062bf9d64120c (diff)
downloadrancid-2.3.rc1.tar.gz
rancid-2.3.rc1.tar.xz
rancid-2.3.rc1.zip
Imported from rancid-2.3.rc1.tar.gz.rancid-2.3.rc1
Diffstat (limited to 'bin/hpfilter.c')
-rw-r--r--bin/hpfilter.c397
1 files changed, 0 insertions, 397 deletions
diff --git a/bin/hpfilter.c b/bin/hpfilter.c
deleted file mode 100644
index 83d799e..0000000
--- a/bin/hpfilter.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 1997-2002 by Henry Kilmer, Erik Sherk and Pete Whiting.
- * All rights reserved.
- *
- * This software may be freely copied, modified and redistributed without
- * fee for non-commerical purposes provided that this copyright notice is
- * preserved intact on all copies and modified copies.
- *
- * There is no warranty or other guarantee of fitness of this software.
- * It is provided solely "as is". The author(s) disclaim(s) all
- * responsibility and liability with respect to this software's usage
- * or its effect upon hardware, computer systems, other software, or
- * anything else.
- *
- *
- * run telnet or ssh to connect to device specified on the command line. the
- * point of hpfilter is to filter all the bloody vt100 (curses) escape codes
- * that the HP procurve switches belch and make hlogin a real bitch.
- */
-
-#define DFLT_TO 60 /* default timeout */
-
-#include <config.h>
-#include <version.h>
-
-#include <stdio.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <regex.h>
-
-#include <termios.h>
-
-char *progname;
-int debug = 0;
-
-int filter __P((char *, int));
-void usage __P((void));
-void vers __P((void));
-RETSIGTYPE reapchild __P((void));
-
-int
-main(int argc, char **argv)
-{
- extern char *optarg;
- extern int optind;
- char ch,
- hbuf[LINE_MAX * 2], /* hlogin buffer */
- *hbufp,
- tbuf[LINE_MAX * 2], /* telnet buffer */
- *tbufp;
- int bytes, /* bytes read/written */
- child,
- r[2], /* recv pipe */
- s[2]; /* send pipe */
- ssize_t hlen = 0, /* len of hbuf */
- tlen = 0; /* len of tbuf */
- struct timeval to = { DFLT_TO, 0 };
- fd_set rfds, /* select() */
- wfds;
- struct termios tios;
-
- /* get just the basename() of our exec() name and strip a .* off the end */
- if ((progname = strrchr(argv[0], '/')) != NULL)
- progname += 1;
- else
- progname = argv[0];
- if (strrchr(progname, '.') != NULL)
- *(strrchr(progname, '.')) = '\0';
-
- while ((ch = getopt(argc, argv, "dhv")) != -1 )
- switch (ch) {
- case 'd':
- debug++;
- break;
- case 'v':
- vers();
- return(EX_OK);
- case 'h':
- default:
- usage();
- return(EX_USAGE);
- }
-
- if (argc - optind != 2) {
- usage();
- return(EX_USAGE);
- }
-
- /* reap our children */
- signal(SIGCHLD, (void *) reapchild);
- signal(SIGHUP, (void *) reapchild);
- signal(SIGINT, (void *) reapchild);
- signal(SIGTERM, (void *) reapchild);
-
- /* create 2 pipes for send/recv and then fork and exec telnet */
- for (child = 3; child < 10; child++)
- close(child);
- if (pipe(s) || pipe(r)) {
- fprintf(stderr, "%s: pipe() failed: %s\n", progname,
- strerror(errno));
- return(EX_TEMPFAIL);
- }
-
- /* if a tty, make it raw as the hp echos _everything_, including
- * passwords.
- */
- if (isatty(0)) {
- if (tcgetattr(0, &tios)) {
- fprintf(stderr, "%s: tcgetattr() failed: %s\n", progname,
- strerror(errno));
- return(EX_OSERR);
- }
- tios.c_lflag &= ~ECHO;
- tios.c_lflag &= ~ICANON;
-#ifdef VMIN
- tios.c_cc[VMIN] = 1;
- tios.c_cc[VTIME] = 0;
-#endif
- if (tcsetattr(0, TCSANOW, &tios)) {
- fprintf(stderr, "%s: tcsetattr() failed: %s\n", progname,
- strerror(errno));
- return(EX_OSERR);
- }
- }
-
- if ((child = fork()) == -1) {
- fprintf(stderr, "%s: fork() failed: %s\n", progname,
- strerror(errno));
- return(EX_TEMPFAIL);
- }
-
- /* zero the buffers */
- bzero(hbuf, LINE_MAX * 2);
- bzero(tbuf, LINE_MAX * 2);
-
- if (child == 0) {
- /* close the parent's side of the pipes; we write r[1], read s[0] */
- close(s[1]);
- close(r[0]);
- /* close stdin/out/err and attach them to the pipes */
- if (dup2(s[0], 0) == -1 || dup2(r[1], 1) == -1 || dup2(r[1], 2) == -1) {
- fprintf(stderr, "%s: dup2() failed: %s\n", progname,
- strerror(errno));
- return(EX_OSERR);
- }
- close(s[0]);
- close(r[1]);
- /* exec telnet */
- if (execvp(argv[optind], argv + optind)) {
- fprintf(stderr, "%s: execlp() failed: %s\n", progname,
- strerror(errno));
- return(EX_TEMPFAIL);
- }
- /* not reached */
- } else {
- /* parent */
- if (debug)
- fprintf(stderr, "child %d\n", child);
-
- /* close the child's side of the pipes; we write s[1], read r[0] */
- close(s[0]);
- close(r[1]);
-
- /* make FDs non-blocking */
- if (fcntl(s[1], F_SETFL, O_NONBLOCK) ||
- fcntl(r[0], F_SETFL, O_NONBLOCK) ||
- fcntl(0, F_SETFL, O_NONBLOCK) ||
- fcntl(1, F_SETFL, O_NONBLOCK)) {
- fprintf(stderr, "%s: fcntl(NONBLOCK) failed: %s\n", progname,
- strerror(errno));
- exit(EX_OSERR);
- }
-
- /* loop to read on stdin and r[0] */
- FD_ZERO(&rfds); FD_ZERO(&wfds);
- hbufp = hbuf; tbufp = tbuf;
-
- while (1) {
- FD_SET(0, &rfds); FD_SET(r[0], &rfds);
- /* if we have stuff in our buffer(s), we select on writes too */
- FD_ZERO(&wfds);
- if (hlen) {
- FD_SET(s[1], &wfds);
- }
- if (tlen) {
- FD_SET(1, &wfds);
- }
-
- switch (select(r[1], &rfds, &wfds, NULL, &to)) {
- case 0:
- /* timeout */
- /* HEAS: what do i do here? */
- break;
- case -1:
- switch (errno) {
- case EINTR: /* interrupted syscall */
- break;
- default:
- exit(EX_IOERR);
- }
- break;
- default:
- /* check exceptions first */
-
- /* which FD is ready? write our buffers asap. */
- /* write hbuf (stdin) -> s[1] */
- if (FD_ISSET(s[1], &wfds) && hlen) {
- if ((hlen = write(s[1], hbuf, hlen)) < 0) {
- fprintf(stderr, "%s: write() failed: %s\n", progname,
- strerror(errno));
- close(s[1]);
- } else
- strcpy(hbuf, hbuf + hlen);
-
- hlen = strlen(hbuf);
- }
- /* write tbuf -> stdout */
- if (FD_ISSET(1, &wfds) && tlen) {
- /* if there is an escape char that didnt get filter()'d,
- * we need to only write up to that point and wait for
- * the bits that complete the escape sequence
- */
- if ((tbufp = index(tbuf, 0x1b)) != NULL)
- tlen = tbufp - tbuf;
-
- if ((tlen = write(1, tbuf, tlen)) < 0) {
- fprintf(stderr, "%s: write() failed: %s\n", progname,
- strerror(errno));
- close(1);
- } else
- strcpy(tbuf, tbuf + tlen);
-
- tlen = strlen(tbuf);
- }
- if (FD_ISSET(0, &rfds)) {
- /* read stdin into hbuf */
- if (LINE_MAX * 2 - hlen > 1) {
- hlen += read(0, hbuf + hlen,
- (LINE_MAX * 2 - 1) - hlen);
- if (hlen > 0) {
- hbuf[hlen] = '\0';
- } else if (hlen == 0 || errno != EAGAIN)
- /* EOF or read error */
- close(0);
-
- hlen = strlen(hbuf);
- }
- } else if (FD_ISSET(r[0], &rfds)) {
- /* read telnet into tbuf, then filter */
- if (LINE_MAX * 2 - tlen > 1) {
- tlen += read(r[0], tbuf + tlen,
- (LINE_MAX * 2 - 1) - tlen);
- if (tlen > 0) {
- tbuf[tlen] = '\0';
- tlen = filter(tbuf, tlen);
- } else if (tlen == 0 || errno != EAGAIN)
- /* EOF or read error */
- close(r[0]);
-
- tlen = strlen(tbuf);
- }
- }
-
- break;
- }
- }
- /* close */
- close(0);
- close(1);
- close(s[1]);
- close(r[0]);
-
- }
-
- if (! kill(child, SIGQUIT))
- reapchild();
-
- return(EX_OK);
-}
-
-int
-filter(buf, len)
- char *buf;
- int len;
-{
- static regmatch_t pmatch[1];
-#define N_REG 11 /* number of regexes in reg[][] */
- static regex_t preg[N_REG];
- static char reg[N_REG][50] = { /* vt100/220 escape codes */
- "\e7\e\\[1;24r\e8", /* ds */
- "\e8", /* fs */
-
- "\e\\[2J",
- "\e\\[2K", /* kE */
-
- "\e\\[[0-9]+;[0-9]+r", /* cs */
- "\e\\[[0-9]+;[0-9]+H", /* cm */
-
- "\e\\[\\?6l",
- "\e\\[\\?7l", /* RA */
- "\e\\[\\?25h", /* ve */
- "\e\\[\\?25l", /* vi */
-
- "\eE", /* replace w/ CR */
- };
- char ebuf[256];
- size_t nmatch = 1;
- int err,
- x;
- static int init = 0;
-
- if (index(buf, 0x1b) == 0 || len == 0)
- return(len);
-
- for (x = 0; x < N_REG - 1; x++) {
- if (! init) {
- if ((err = regcomp(&preg[x], reg[x], REG_EXTENDED))) {
- regerror(err, &preg[x], ebuf, 256);
- fprintf(stderr, "%s: regex compile failed: %s\n", progname,
- ebuf);
- abort();
- }
- }
- if ((err = regexec(&preg[x], buf, nmatch, pmatch, 0))) {
- if (err != REG_NOMATCH) {
- regerror(err, &preg[x], ebuf, 256);
- fprintf(stderr, "%s: regexec failed: %s\n", progname, ebuf);
- abort();
- }
- } else {
- strcpy(buf + pmatch[0].rm_so, buf + pmatch[0].rm_eo);
- x = 0;
- }
- }
-
- /* replace \eE w/ CR NL */
- if (! init++) {
- if ((err = regcomp(&preg[N_REG - 1], reg[N_REG - 1], REG_EXTENDED))) {
- regerror(err, &preg[N_REG - 1], ebuf, 256);
- fprintf(stderr, "%s: regex compile failed: %s\n", progname,
- ebuf);
- abort();
- }
- }
- while (1)
- if ((err = regexec(&preg[N_REG - 1], buf, nmatch, pmatch, 0))) {
- if (err != REG_NOMATCH) {
- regerror(err, &preg[N_REG - 1], ebuf, 256);
- fprintf(stderr, "%s: regexec failed: %s\n", progname, ebuf);
- abort();
- } else
- break;
- } else {
- *(buf + pmatch[0].rm_so) = '\n';
- strcpy(buf + pmatch[0].rm_so + 1, buf + pmatch[0].rm_eo);
- x = 0;
- }
-
- return(strlen(buf));
-}
-
-RETSIGTYPE
-reapchild(void)
-{
- int status;
- pid_t pid;
-
- /* HEAS: this needs to deal with/without wait3 via HAVE_WAIT3 */
- while ((pid = wait3(&status, WNOHANG, 0)) > 0)
- if (debug)
- fprintf(stderr, "reap child %d\n", pid);
-
- /*exit(1);*/
-return;
-
- /* not reached */
-}
-
-void
-usage(void)
-{
- fprintf(stderr,
-"usage: %s [-hv] <telnet|ssh> <hostname>
-", progname);
- return;
-}
-
-void
-vers(void)
-{
- fprintf(stderr,
-"%s: %s version %s
-", progname, package, version);
- return;
-}