📄 tip.c
字号:
/*****************************************************************************//* * tip.c -- simple tip/cu program. * * (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2002, SnapGear Inc (www.snapgear.com) * * Modified 5 May 2000, Rick Stevenson. * Added -f option to pass XON/XOFF characters through * to remote end. * * Modified 020131, Heiko Degenhardt (heiko.degenhardt@sentec-elektronik.de) * - Added signal handler to restore the termios * - Introduced SaveRemoteTermIOs/RestoreRemoteTermIOs to * correctly leave the remote side. * - Introduced a global var that holds the file pointer * (FIXME: Don't know if a global var is the right thing!) * * Modified 2003/04/20 David McCullough <davidm@snapgear.com> * added file download option * * Modified 2004/01/21 David McCullough <davidm@snapgear.com> * connect to IP:PORT instead of serial port * * Modified 2004/06/28 David McCullough <davidm@snapgear.com> * add ~b (send break) escape code * * Modified 2004/08/16 Peter Hunt <pchunt@snapgear.com> * -l can now take a relative device path from "/dev/" as well (like cu). *//*****************************************************************************/#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <getopt.h>#include <errno.h>#include <string.h>#include <signal.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/termios.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifndef EMBED#include <sys/select.h>#endif/*****************************************************************************/char *version = "1.1.0";/*****************************************************************************//* * Define some parity flags, internal use only. */#define PARITY_NONE 0#define PARITY_EVEN 1#define PARITY_ODD 2/* * Default port settings. */int clocal;int hardware;int software;int passflow;int parity = PARITY_NONE;int databits = 8;int twostopb;unsigned int baud = 9600;unsigned short tcpport;int translate;int ocasemode, icasemode;char *devname;char *filename;char *capfile;int verbose = 1;int net_connection = 0;int gotdevice;int ifd, ofd;int rfd, cfd;/* * Working termios settings. */struct termios savetio_local;struct termios savetio_remote;/* * Signal handling. */struct sigaction sact;/* * Temporary buffer to use when working. */unsigned char ibuf[512];unsigned char obuf[1024];/*****************************************************************************//* * Baud rate table for baud rate conversions. */typedef struct baudmap { unsigned int baud; unsigned int flag;} baudmap_t;struct baudmap baudtable[] = { { 0, B0 }, { 50, B50 }, { 75, B75 }, { 110, B110 }, { 134, B134 }, { 150, B150 }, { 200, B200 }, { 300, B300 }, { 600, B600 }, { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, { 4800, B4800 }, { 9600, B9600 }, { 19200, B19200 }, { 38400, B38400 }, { 57600, B57600 }, { 115200, B115200 }, { 230400, B230400 }, { 460800, B460800 }};#define NRBAUDS (sizeof(baudtable) / sizeof(struct baudmap))/*****************************************************************************//* * Verify that the supplied baud rate is valid. */int baud2flag(unsigned int speed){ int i; for (i = 0; (i < NRBAUDS); i++) { if (speed == baudtable[i].baud) return(baudtable[i].flag); } return(-1);}/*****************************************************************************/void restorelocaltermios(void){ if (tcsetattr(1, TCSAFLUSH, &savetio_local) < 0) { fprintf(stderr, "ERROR: local tcsetattr(TCSAFLUSH) failed, " "errno=%d\n", errno); }}/*****************************************************************************/void savelocaltermios(void){ if (tcgetattr(1, &savetio_local) < 0) { fprintf(stderr, "ERROR: local tcgetattr() failed, errno=%d\n", errno); exit(0); }}/*****************************************************************************/void restoreremotetermios(void){ /* * This can fail if remote hung up, don't check return status. */ tcsetattr(rfd, TCSAFLUSH, &savetio_remote);}/*****************************************************************************/int saveremotetermios(void){ if (tcgetattr(rfd, &savetio_remote) < 0) { fprintf(stderr, "ERROR: remote tcgetattr() failed, errno=%d\n", errno); return(0); } return(1);}/*****************************************************************************//* * Set local port to raw mode, no input mappings. */int setlocaltermios(){ struct termios tio; if (tcgetattr(1, &tio) < 0) { fprintf(stderr, "ERROR: local tcgetattr() failed, errno=%d\n", errno); exit(1); } if (passflow) tio.c_iflag &= ~(ICRNL|IXON); else tio.c_iflag &= ~ICRNL; tio.c_lflag = 0; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(1, TCSAFLUSH, &tio) < 0) { fprintf(stderr, "ERROR: local tcsetattr(TCSAFLUSH) failed, " "errno=%d\n", errno); exit(1); } return(0);}/*****************************************************************************//* * Set up remote (connect) port termio settings according to * user specification. */int setremotetermios(){ struct termios tio; memset(&tio, 0, sizeof(tio)); tio.c_cflag = CREAD | HUPCL | baud2flag(baud); if (clocal) tio.c_cflag |= CLOCAL; switch (parity) { case PARITY_ODD: tio.c_cflag |= PARENB | PARODD; break; case PARITY_EVEN: tio.c_cflag |= PARENB; break; default: break; } switch (databits) { case 5: tio.c_cflag |= CS5; break; case 6: tio.c_cflag |= CS6; break; case 7: tio.c_cflag |= CS7; break; default: tio.c_cflag |= CS8; break; } if (twostopb) tio.c_cflag |= CSTOPB; if (software) tio.c_iflag |= IXON | IXOFF; if (hardware) tio.c_cflag |= CRTSCTS; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(rfd, TCSAFLUSH, &tio) < 0) { fprintf(stderr, "ERROR: remote tcsetattr(TCSAFLUSH) failed, " "errno=%d\n", errno); return(0); } return(1);}/*****************************************************************************/void sighandler(int signal){ if (tcpport) { close(ifd); close(ofd); } else { printf("\n\nGot signal %d!\n", signal); printf("Cleaning up..."); restorelocaltermios(); restoreremotetermios(); printf("Done\n"); } close(rfd); exit(1);}/*****************************************************************************//* * Code to support 5bit translation to ascii. * Whacky 5 bit system used on some older teletype equipment. */unsigned char ascii2code[128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x85, 0x96, 0x00, 0x94, 0x97, 0x89, 0x00, 0x91, 0x86, 0x98, 0x87, 0x97, 0x8d, 0x9d, 0x99, 0x90, 0x8a, 0x81, 0x95, 0x9c, 0x8c, 0x83, 0x8e, 0x00, 0x00, 0x8f, 0x00, 0x93, 0x8b, 0x18, 0x13, 0x0e, 0x12, 0x10, 0x16, 0x0a, 0x05, 0x0c, 0x1a, 0x1e, 0x09, 0x07, 0x06, 0x03, 0x0d, 0x1d, 0x0a, 0x14, 0x01, 0x1c, 0x0f, 0x19, 0x17, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x13, 0x0e, 0x12, 0x10, 0x16, 0x0a, 0x05, 0x0c, 0x1a, 0x1e, 0x09, 0x07, 0x06, 0x03, 0x0d, 0x1d, 0x0a, 0x14, 0x01, 0x1c, 0x0f, 0x19, 0x17, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,};unsigned char lower2ascii[32] = { 0x00, 0x74, 0x0d, 0x6f, 0x20, 0x68, 0x6e, 0x6d, 0x0a, 0x6c, 0x72, 0x67, 0x69, 0x70, 0x63, 0x76, 0x65, 0x7a, 0x64, 0x62, 0x73, 0x79, 0x66, 0x78, 0x61, 0x77, 0x6a, 0x80, 0x75, 0x71, 0x6b, 0x80,};unsigned char upper2ascii[32] = { 0x00, 0x35, 0x0d, 0x39, 0x20, 0x24, 0x2c, 0x2e, 0x0a, 0x29, 0x34, 0x40, 0x38, 0x30, 0x3a, 0x3d, 0x33, 0x2b, 0x00, 0x3f, 0x27, 0x36, 0x25, 0x2f, 0x2d, 0x32, 0x07, 0x80, 0x37, 0x31, 0x28, 0x80,};int translateread(unsigned char *ip, unsigned char *op, int n){ unsigned char *sop, c; int i; for (sop = op, i = 0; (i < n); i++) { c = *ip++; if (c == 0x1f) icasemode = 0; else if (c == 0x1b) icasemode = 1; else c = (icasemode) ? upper2ascii[c] : lower2ascii[c]; *op++ = c; } return(op - sop);}int translatewrite(unsigned char *ip, unsigned char *op, int n){ unsigned char *sop, c; int i; for (sop = op, i = 0; (i < n); i++) { c = *ip++; c = ascii2code[c & 0x7f]; if (ocasemode && ((c & 0x80) == 0)) { *op++ = 0x1f; ocasemode = 0; } if ((ocasemode == 0) && (c & 0x80)) { *op++ = 0x1b; ocasemode = 1; } *op++ = (c & 0x1f); } return(op - sop);}/*****************************************************************************//* * Send the file named on the command line to the remote end */void send_file(){ int fd, n, rc; char *bp; fd_set infds, outfds; fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "ERROR: open(%s) failed, errno=%d\n", filename, errno); return; } while ((n = read(fd, ibuf, sizeof(ibuf))) > 0) { bp = ibuf; while (n > 0) { FD_ZERO(&outfds); FD_SET(rfd, &infds); FD_SET(rfd, &outfds); if (select(rfd + 1, &infds, &outfds, NULL, NULL) <= 0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -