Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/*
* ek -- serial external keyboard :-) for FreeBSD/Linux
*
* revision history
* 0.0: Feb. 5, 2003 by Dai ISHIJIMA
*
* usage: ek [serial device]
*
* example: ek /dev/ttyS1
*
* see also: source of ``script'' command
*/
#include
#include
#include
#include
#include /* bzero() <- FDZERO() */
#include
#include
#include
#ifndef LINUX
#include /* openpty() */ /* -lutil */
#else
#include
#include
#endif
#include
#include
#include
#include "tty.h"
#ifdef LINUX
#define DEFAULT_SHELL "/bin/sh"
#ifdef SLZAURUS
#define DEFAULT_DEVICE "/dev/ttyS1" /* raw IrDA */
#else
#define DEFAULT_DEVICE "/dev/ttyS0" /* COM1: */
#endif
#else
#define DEFAULT_SHELL "/bin/csh"
#define DEFAULT_DEVICE "/dev/ttyd0" /* COM1: */
#endif
#define DEFAULT_SPEED 9600
#define RAW_KEYBOARD 'r'
#define EK_ENVIRON "EXTERNAL_KEYBOARD"
#define EK_VALUE "SERIAL"
#define SHELL_ENV "SHELL"
#define ENV_OVERWRITE 1
#define RUNNING 'r'
#define YES 1
#define NO 0
char *prog;
#define shift --argc; ++argv
static int childstatus = RUNNING;
/*
* 仮想端末関連
*/
/* 子プロセスとしてシェルを起動する */
void subshell(int master, int slave)
{
char *keyenv;
char *shell;
/* すでにキーボードがフックされているか? */
keyenv = getenv(EK_ENVIRON);
if (keyenv != NULL) {
fprintf(stderr, "%s: may already running %s, ", prog, prog);
fprintf(stderr, "environ $%s set, value = %s\r\n", EK_ENVIRON, keyenv);
}
setenv(EK_ENVIRON, EK_VALUE, ENV_OVERWRITE);
/* 起動するシェルを決める */
shell = getenv(SHELL_ENV);
if (shell == NULL) {
shell = DEFAULT_SHELL;
}
close(master);
login_tty(slave);
execl(shell, "sh", "-i", NULL); /* シェルを「対話モード」で起動 */
/* ここから下は実行されないはず… */
fprintf(stderr, "%s: can't start subshell (%s)\r\n", prog, shell);
kill(0, SIGTERM);
exit(1);
}
#ifdef LINUX
void finish(int dummy)
{
childstatus = SIGCHLD;
}
#endif
/* 仮想端末を開く */
void pseudoterm(int extkey, int mode)
{
struct termios t; /* 端末の設定 */
struct termios tsave; /* 端末の設定 */
struct winsize w; /* 端末の画面サイズ */
pid_t child;
int nfds;
fd_set readfds;
struct timeval *timeout = NULL;
int n; /* 読み込んだ文字の数 */
int master, slave;
char buf[BUFSIZ];
tcgetattr(fileno(stdin), &t);
tcgetattr(fileno(stdin), &tsave);
ioctl(fileno(stdin), TIOCGWINSZ, &w);
if (openpty(&master, &slave, NULL, &t, &w) != 0) {
fprintf(stderr, "%s: can't open pty\n", prog);
exit(1);
}
cfmakeraw(&t);
t.c_lflag &= ~ECHO;
(void)tcsetattr(fileno(stdin), TCSAFLUSH, &t);
#ifdef LINUX
(void)signal(SIGCHLD, finish);
#endif
childstatus = RUNNING;
child = fork();
if (child < 0) { /* fork失敗 */
fprintf(stderr, "%s: can't fork\n", prog);
exit(1);
}
else if (child == 0) { /* 子プロセス */
subshell(master, slave);
}
else { /* 元々のプロセス */
fprintf(stderr, "%s: external keyboard now enabled\r\n", prog);
while (ttygetc(extkey) != EOF) {
; /* 起動時のごみキャラクタを読み飛ばす */
}
while (childstatus == RUNNING) {
FD_ZERO(&readfds);
FD_SET(master, &readfds); /* 子プロセスの出力を調べる */
FD_SET(fileno(stdin), &readfds); /* 標準入力 (本体キー) を調べる */
FD_SET(extkey, &readfds); /* 外部キーボードを調べる */
nfds = select(master + 1, &readfds, NULL, NULL, timeout);
if ((nfds < 0) && (errno != EINTR)) {
fprintf(stderr, ">>>if ((nfds < 0) && (errno != EINTR)) {\n");
break;
}
if ((nfds > 0) && (FD_ISSET(fileno(stdin), &readfds))) {
/* 標準入力 (本体キーボード) からのデータを */
/* 子プロセスに書き込む */
n = read(fileno(stdin), buf, BUFSIZ);
if (n <= 0) {
break;
}
if (n > 0) {
(void)write(master, buf, n);
}
}
if ((nfds > 0) && (FD_ISSET(extkey, &readfds))) {
/* 外部キーボードからのデータを子プロセスに書き込む */
n = read(extkey, buf, BUFSIZ);
if (n <= 0) {
break;
}
if (n > 0) {
(void)write(master, buf, n);
}
}
if (nfds > 0 && FD_ISSET(master, &readfds)) {
/* 子プロセスからのデータを標準出力へ書き出す */
n = read(master, buf, BUFSIZ);
if (n <= 0) {
childstatus = EOF;
break;
}
write(fileno(stdout), buf, n);
}
} /* while */
if (childstatus == EOF) {
fprintf(stderr, "%s: EOF encountered, child process finished\r\n",
prog);
}
else if (childstatus == SIGCHLD) {
fprintf(stderr, "%s: caught SIGCHLD, child process finished\r\n",
prog);
}
else {
fprintf(stderr, "%s: child process finished\r\n", prog);
}
fprintf(stderr, "%s: external keyboard now disabled\r\n", prog);
}
(void)tcsetattr(fileno(stdin), TCSAFLUSH, &tsave);
}
void usage()
{
fprintf(stderr, "Usage: %s [option]...\n", prog);
}
int main(int argc, char *argv[])
{
int mode;
char *keydev;
int fd;
int speed;
prog = *argv;
shift;
speed = DEFAULT_SPEED;
mode = RAW_KEYBOARD;
while ((argc > 0) && (argv[0][0] == '-')) {
if (argv[0][1] == 'r') {
mode = RAW_KEYBOARD;
}
else {
usage();
exit(1);
}
shift;
}
if (argc > 0) {
keydev = *argv;
}
else {
keydev = DEFAULT_DEVICE;
}
fd = opentty(keydev);
ttyinit(fd, speed);
pseudoterm(fd, mode);
closetty(fd);
exit(0);
}
/* Local Variables: */
/* compile-command:"gcc -g -Wall -o ek ek.c tty.c -lutil" */
/* End: */