/* con device */ /* vim: set noexpandtab sw=8 : */ #include #include #include #include #include #include #include struct termios save; void host(int fd) { int cc; char buf; #ifndef HEX char last = '\r'; #endif for (;;) { cc = read(fd, &buf, 1); if (cc < 0) break; if (cc) { #ifdef HEX char hex[3]; sprintf(hex, "%02X", (unsigned char) buf); write(1, hex, 2); #else if (buf == '\n' && last != '\r') write(1, "\r", 1); write(1, &buf, 1); last = buf; #endif } } } void hup(int signo) { write(1, "HUP\n", 4); tcsetattr(0, TCSADRAIN, &save); _exit(0); } void user(int fd) { char c, last = '\r'; signal(SIGHUP, hup); for (;;) while (read(0, &c, 1) > 0) { if (c == '~' && (last == '\n' || last == '\r' || last == 4)) { read(0, &c, 1); if (c == '.') return; } #ifdef HEX char hex[5]; sprintf(hex, "<%02X>", (unsigned char) c); write(1, hex, 4); #endif #ifdef SEND_CRLF if (c == '\n' && last != '\r') write(fd, "\r", 1); #endif write(fd, &c, 1); last = c; } } int main(int argc, char *argv[]) { int fd; pid_t pid; struct termios t; if (argc != 2) exit(1); fd = open(argv[1], O_RDWR | O_NDELAY); if (fd < 0) exit(2); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY); tcgetattr(fd, &t); t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fd, TCSADRAIN, &t); tcgetattr(0, &t); save = t; t.c_iflag = 0; t.c_oflag = 0; t.c_lflag = 0; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(0, TCSADRAIN, &t); if ((pid = fork()) > 0) { user(fd); } else if (pid == 0) { host(fd); } else { perror("fork"); _exit(EXIT_FAILURE); } tcsetattr(0, TCSADRAIN, &save); kill(pid, SIGKILL); close(fd); _exit(EXIT_SUCCESS); }