This commit is contained in:
Ugen J.S. Antsilevich 1995-02-27 19:48:19 +00:00
parent 0739a0dc6e
commit c120979990
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6775
2 changed files with 47 additions and 13 deletions

View File

@ -9,9 +9,9 @@
.Nd snoop on another tty line .Nd snoop on another tty line
.Sh SYNOPSYS .Sh SYNOPSYS
.Nm watch .Nm watch
.Op Fl ciot .Op Fl ciotW
.Ar tty .Ar tty
.\" watch [-ciot] [<tty name>] .\" watch [-ciotW] [<tty name>]
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm Watch .Nm Watch
allows the superuser to examine all data coming through a specified tty. allows the superuser to examine all data coming through a specified tty.
@ -45,6 +45,8 @@ For more info see
.Xr snp 4 . .Xr snp 4 .
.It Fl t .It Fl t
Print the date and time when observation of a given tty is started. Print the date and time when observation of a given tty is started.
.It Fl W
Allow write access to observed tty.
.It Ar tty .It Ar tty
Tty may be specified as an tty-style device, such as a pseudo tty device, Tty may be specified as an tty-style device, such as a pseudo tty device,
a virtual console, or a serial line, etc. a virtual console, or a serial line, etc.

View File

@ -17,6 +17,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
@ -31,6 +32,7 @@
#define MSG_OFLOW "Snoop stopped due to overflow. Reconnecting." #define MSG_OFLOW "Snoop stopped due to overflow. Reconnecting."
#define MSG_CLOSED "Snoop stopped due to tty close. Reconnecting." #define MSG_CLOSED "Snoop stopped due to tty close. Reconnecting."
#define MSG_CHANGE "Snoop device change by user request." #define MSG_CHANGE "Snoop device change by user request."
#define MSG_NOWRITE "Snoop device change due to write failure."
#define DEV_NAME_LEN 1024 /* for /dev/ttyXX++ */ #define DEV_NAME_LEN 1024 /* for /dev/ttyXX++ */
@ -44,6 +46,7 @@ int opt_reconn_close = 0;
int opt_reconn_oflow = 0; int opt_reconn_oflow = 0;
int opt_interactive = 1; int opt_interactive = 1;
int opt_timestamp = 0; int opt_timestamp = 0;
int opt_write = 0;
char dev_name[DEV_NAME_LEN]; char dev_name[DEV_NAME_LEN];
int snp_io; int snp_io;
@ -112,12 +115,18 @@ fatal(buf)
int int
open_snp() open_snp()
{ {
char *snp = "/dev/snpX"; char snp[] = {"/dev/snpX"};
char c; char c;
int f; int f, mode;
if (opt_write)
mode = O_RDWR;
else
mode = O_RDONLY;
for (c = '0'; c <= '9'; c++) { for (c = '0'; c <= '9'; c++) {
snp[8] = c; snp[8] = c;
if ((f = open(snp, O_RDONLY)) < 0) if ((f = open(snp, mode)) < 0)
continue; continue;
return f; return f;
} }
@ -139,7 +148,7 @@ cleanup()
void void
show_usage() show_usage()
{ {
printf("watch -[ciot] [tty name]\n"); printf("watch -[ciotW] [tty name]\n");
exit(1); exit(1);
} }
@ -199,10 +208,13 @@ set_dev(name)
struct stat sb; struct stat sb;
if (strlen(name) > 5 && !strncmp(name, "/dev/", 5)) if (strlen(name) > 5 && !strncmp(name, "/dev/", 5))
strcpy(buf, &(name[5]));
else
strcpy(buf, name); strcpy(buf, name);
else {
if (strlen(name) == 2)
sprintf(buf, "/dev/tty%s", name);
else
sprintf(buf, "/dev/%s", name);
}
if (stat(buf, &sb) < 0) if (stat(buf, &sb) < 0)
fatal("Bad device name."); fatal("Bad device name.");
@ -238,6 +250,7 @@ ask_dev(dev_name, msg)
set_tty(); set_tty();
} }
#define READB_LEN 5
void void
main(ac, av) main(ac, av)
@ -246,7 +259,7 @@ main(ac, av)
{ {
int res, nread, b_size = MIN_SIZE; int res, nread, b_size = MIN_SIZE;
extern int optind; extern int optind;
char ch, *buf; char ch, *buf, chb[READB_LEN];
fd_set fd_s; fd_set fd_s;
if (getuid() != 0) if (getuid() != 0)
@ -258,8 +271,11 @@ main(ac, av)
opt_interactive = 0; opt_interactive = 0;
while ((ch = getopt(ac, av, "ciot")) != EOF) while ((ch = getopt(ac, av, "Wciot")) != EOF)
switch (ch) { switch (ch) {
case 'W':
opt_write = 1;
break;
case 'c': case 'c':
opt_reconn_close = 1; opt_reconn_close = 1;
break; break;
@ -304,16 +320,32 @@ main(ac, av)
FD_SET(snp_io, &fd_s); FD_SET(snp_io, &fd_s);
res = select(snp_io + 1, &fd_s, NULL, NULL, NULL); res = select(snp_io + 1, &fd_s, NULL, NULL, NULL);
if (opt_interactive && FD_ISSET(std_in, &fd_s)) { if (opt_interactive && FD_ISSET(std_in, &fd_s)) {
switch (ch = getchar()) {
if ((res = ioctl(std_in, FIONREAD, &nread)) != 0)
fatal("ioctl() failed.");
if (nread > READB_LEN)
nread = READB_LEN;
if (read(std_in,chb,nread)!=nread)
fatal("read (stdin) failed.");
switch (chb[0]) {
case CHR_CLEAR: case CHR_CLEAR:
clear(); clear();
break; break;
case CHR_SWITCH: case CHR_SWITCH:
/* detach_snp(); */ detach_snp();
ask_dev(dev_name, MSG_CHANGE); ask_dev(dev_name, MSG_CHANGE);
set_dev(dev_name); set_dev(dev_name);
break; break;
default: default:
if (opt_write) {
if (write(snp_io,chb,nread) != nread) {
detach_snp();
ask_dev(dev_name, MSG_NOWRITE);
set_dev(dev_name);
}
}
} }
} }
if (!FD_ISSET(snp_io, &fd_s)) if (!FD_ISSET(snp_io, &fd_s))