#include <stdio.h>
#include <sys/types.h> /* for stat(2) */
#include <sys/stat.h> /* for stat(2) */
#include <sys/termio.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
/*
#define TCGETS TCGETA
#define TCSETS TCSANOW
#define TCFLSH I_FLUSH
*/
void push(), devchk();
extern char *optarg;
extern int optind;
short no_echo = 0;
#define USAGE "usage: %s [-n] [-l /dev/ttyxx]\n",*argv
#define COMMAND_LIM 100
int
main(argc, argv)
int argc;
char **argv;
{
int f, cnt;
short true = 1, no_cmd = 0;
char *device, *buf, *trail, chr;
if (argc > 4) {
fprintf(stderr, USAGE);
exit(1);
}
if ((device = (char *)malloc(40)) == (char *)NULL) {
perror("malloc 1");
exit(1);
}
if ((buf = (char *) malloc(COMMAND_LIM)) == (char *)NULL) {
perror("malloc 1a");
exit(1);
}
while ((chr = getopt(argc, argv, "nl:")) != -1)
switch (chr) {
case 'n':
no_echo = 1;
break;
case 'l':
(void) devchk(optarg, *argv);
device = optarg;
break;
default:
fprintf(stderr, USAGE);
exit(1);
}
if (strlen(device) < 2) {
printf("Device [form: /dev/ttyxx]: ");
fflush(stdout);
fgets(device, 39, stdin);
/* cut off the trailing return that fgets leaves on */
if ((*device) && (*(trail=(char *)(device + strlen(device) - 1)) == '\n'))
*trail = '\0';
(void) devchk(device, *argv);
}
printf("Terminate with '-X-' on a line by itself.\n");
while (true) {
no_cmd = cnt = 0;
chr = *buf = '\0';
printf("Force> ");
rewind(stdin);
while (((chr=getchar()) != '\n') && (chr != EOF) && (cnt < COMMAND_LIM))
*(buf + cnt++) = chr;
if (cnt == COMMAND_LIM) {
printf("Limit of %d characters per command line.\n", COMMAND_LIM);
no_cmd = 1;
}
if (chr == EOF) {
putc('\n', stdout);
exit(0);
}
if (!no_cmd) {
*(buf + cnt) = '\0';
if (!strcmp(buf, "-X-"))
true = 0;
else if ((*buf != '\n') && (*buf != '\0')) {
if ((f = open(device, O_NDELAY | O_RDWR)) < 0) {
perror("open");
exit(1);
}
push(f, buf);
close(f);
}
}
}
}
void
push(f, s)
int f;
char *s;
{
register int i;
char ret='\n';
struct termios termios;
if (no_echo) {
if (ioctl(f, TCGETS, &termios) < 0) {
perror("ioctl 1");
exit(1);
}
termios.c_lflag &= ~ECHO;
if (ioctl(f, TCSETS, &termios) < 0) {
perror("ioctl 2");
exit(1);
}
}
if (ioctl(f, TCFLSH, 0) < 0) { /* flush the input queue */
perror("ioctl 3");
exit(1);
}
for (i = 0; i < strlen(s); i++) /* give 'em the command */
ioctl(f, TIOCSTI, s + i);
ioctl(f, TIOCSTI, &ret); /* including a return */
if (no_echo) {
ioctl(f, TCGETS, &termios);
termios.c_lflag |= ECHO;
ioctl(f, TCSETS, &termios);
ioctl(f, TCFLSH, 1); /* flush the output queue */
}
}
void
devchk(device, prg)
char *device, *prg;
{
struct stat sb;
if (!strcmp(device, ttyname(0))) {
fprintf(stderr, "%s: you can't force yourself, you masochist.\n",
prg);
exit(1);
}
if (strlen(device) > 40) {
fprintf(stderr, "%s: terminal name too long.\n", prg);
exit(1);
}
/*
* there's probably a cleaner way to do this (not having the struct down
* here at all); I considered using alloca, then decided not to. I'm open
* to suggestions. - BK 11/20
*/
if (stat(device, (struct stat *)&sb) < 0) {
perror(prg);
exit(1);
}
}
Received on Thu Dec 12 1996 - 23:23:54 NZDT