📄 vmcp.c
字号:
{ sent_one_dle = TRUE; if (ungetc(c, inp_fp) == EOF) fatal(ERR_WRITE); } else sent_one_dle = FALSE; } else { /* Error writing, check for error type. */ if (errno == EAGAIN) { /* May be buffer full, retry later. */ if (ungetc(c, inp_fp) == EOF) fatal(ERR_WRITE); } else fatal(ERR_WRITE); } } } else { /* No more char to send, can wait chars from kbd or device. */ FD_ZERO(&rfds); if (break_on_key) FD_SET(0, &rfds); FD_SET(fd, &rfds); /* Sleep until chars ready for reading. */ select(fd + 1, &rfds, NULL, NULL, NULL); } /* Read a character from device, escape DLE if required. */ if (read(fd, &buf, 1) == 1) { if (escaping_dle) if (previous_dle) { previous_dle = FALSE; if (buf == DLE) finito = out_chr((int)buf); else finito = out_esc((int)buf); } else if (buf == DLE) previous_dle = TRUE; else finito = out_chr((int)buf); else finito = out_chr((int)buf); } /* Check BREAK_KEY pressed. */ if (break_on_key) if ((getchar() == BREAK_KEY)) { ok_exit_code = EXIT_KEYPRESS; finito = TRUE; } } /* Close input, output, escape files and modem device. */ i = 0; if (fclose(inp_fp) == EOF) i += 1; if (fclose(out_fp) == EOF) i += 2; if (fclose(esc_fp) == EOF) i += 4; if (flock(fd, LOCK_UN) == -1) i += 8; if (close(fd) == -1) i += 16; if (i) { if (debug) fprintf(stderr, "Close error: %d\n", i); fatal(ERR_CLOSE); } else fatal(ok_exit_code); }/*----------------------------------------------------------------------*//* Write c to output file, return TRUE if received out_string. *//*----------------------------------------------------------------------*/int out_chr(int c) { if (!skip_out_string) fputc(c, out_fp); if (out_string == NULL) return FALSE; else { if ((unsigned char)c == out_string[out_pos]) out_pos++; else out_pos = 0; if (out_pos == out_len) if (skip_out_string) { skip_out_string = FALSE; free(out_string); out_string = NULL; return FALSE; } else { ok_exit_code = EXIT_OK; return TRUE; } else return FALSE; } }/*----------------------------------------------------------------------*//* Write c to escape file, return TRUE if c is in esc_string. *//*----------------------------------------------------------------------*/int out_esc(int c) { int i; fputc(c, esc_fp); if (esc_string == NULL) return FALSE; else { for (i = 0; esc_string[i] != '\0' && esc_string[i] != (unsigned char)c; i++); if (esc_string[i] == '\0') return FALSE; else { ok_exit_code = ++i; return TRUE; } } }/*----------------------------------------------------------------------*//* Timeout: exit program. *//*----------------------------------------------------------------------*/void no_response(int i) { fatal(EXIT_TIMEOUT); }/*----------------------------------------------------------------------*//* Signal: exit program. *//*----------------------------------------------------------------------*/void end_on_signal(int i) { fatal(ERR_SIGNAL + i); }/*----------------------------------------------------------------------*//* Fatal errors handling. *//*----------------------------------------------------------------------*/void fatal(int exit_code) { /* Restore standard input line settings earlier saved. */ if (break_on_key) if (changed_std_input) if (ioctl(0, TCSETS, &ts) != 0) if (debug) fprintf(stderr, "ioctl(2) error %d\n", errno); /* Remove lock file if required. */ if (made_lock_file) if (unlink(lckfname) != 0) if (debug) fprintf(stderr, "Can't remove %s", lckfname); if (debug) fprintf(stderr, "Exit code %d\n", exit_code); exit(exit_code); }/*----------------------------------------------------------------------*//* Make a duplicate of the string, do some backslash parsing, add CR. *//*----------------------------------------------------------------------*/char *strdupcvt(char *str) { unsigned char *newstr, *pt1, *pt2; int i, addcr = TRUE; /* Allocate max space for new string. */ if ((newstr = (unsigned char*)malloc(strlen(str) + 3)) != NULL) { strcpy(newstr, str); for (pt1 = pt2 = newstr; *pt1; pt1++, pt2++) { if (*pt1 != '\\') *pt2 = *pt1; else { pt1++; switch (*pt1) { case 'c': pt2--; addcr = FALSE; break; case 'n': *pt2 = '\n'; break; case 'r': *pt2 = '\r'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': *pt2 = 0; for (i = 0; i < 3 && *pt1 && *pt1 >= '0' && *pt1 <= '7'; i++, pt1++) *pt2 = (*pt2 << 3) + (*pt1 & 7); pt1--; break; default: pt1--; *pt2 = *pt1; break; } } } if (addcr) *(pt2++) = '\r'; *pt2 = '\0'; } return newstr; }/*----------------------------------------------------------------------*//* Print msg and str. Unprintable chars in str are printed in hex. *//*----------------------------------------------------------------------*/void safeprint(char *msg, char *str) { int i; fprintf(stderr, "%s ", msg); for (i = 0; str[i]; i++) { if (str[i] >= ' ' && str[i] <= '~') fprintf(stderr, "%c", str[i]); else fprintf(stderr, " 0x%02x", str[i]); } fprintf(stderr, "\n"); }/*----------------------------------------------------------------------*//* Set the serial line to raw, etc. *//*----------------------------------------------------------------------*/void port_reset(int fd) { int line; struct termios ts; /* Flush input and output queues. */ if (ioctl(fd, TCFLSH, 2) != 0) fatal(ERR_IOCTL); /* Turn off DTR control line. */ line = TIOCM_DTR; if (ioctl(fd, TIOCMBIC, &line) != 0) fatal(ERR_IOCTL); /* Pauses for 3 seconds. */ /* No modem should resist over 3 seconds with */ /* DTR off: they return at least in command mode! */ sleep(3); /* Turn on DTR control line. */ line = TIOCM_DTR; if (ioctl(fd, TIOCMBIS, &line) != 0) fatal(ERR_IOCTL); /* Fetch the current terminal parameters. */ if (ioctl(fd, TCGETS, &ts) != 0) fatal(ERR_IOCTL); /* Sets hardware control flags: */ /* 8 data bits */ /* Enable receiver */ /* Ignore CD (local connection) */ /* Use RTS/CTS flow control */ ts.c_cflag = CS8 | CREAD | CLOCAL | CRTSCTS; ts.c_iflag = 0; ts.c_oflag = NL0 | CR0 | TAB0 | BS0 | VT0 | FF0; ts.c_lflag = 0; switch ((int)(baud_rate / 100)) { case 96: ts.c_cflag |= B9600; break; case 192: ts.c_cflag |= B19200; break; case 384: ts.c_cflag |= B38400; break; case 576: ts.c_cflag |= B57600; break; case 1152: ts.c_cflag |= B115200; break; case 2304: ts.c_cflag |= B230400; break; default: fatal(ERR_BAUDRATE); break; } /*-----------------------------------------------------------*/ /* All these capabilities are turned off; see termios(2) */ /* and stty(1L) man pages: */ /* */ /* c_cflag CSTOPB PARENB HUPCL */ /* */ /* c_iflag IGNBRK BRKINT IGNPAR PARMRK INPCK */ /* ISTRIP INLCR IGNCR ICRNL IXON */ /* IXOFF IUCLC IXANY IMAXBEL */ /* */ /* ts.c_oflag OPOST OLCUC OCRNL ONLCR ONOCR */ /* ONLRET OFILL OFDEL */ /* */ /* ts.c_lflag ISIG ICANON IEXTEN ECHO ECHOE */ /* ECHOK ECHONL NOFLSH XCASE TOSTOP */ /* ECHOPRT ECHOCTL ECHOKE */ /*-----------------------------------------------------------*/ ts.c_cc[VINTR] = '\0'; ts.c_cc[VQUIT] = '\0'; ts.c_cc[VERASE] = '\0'; ts.c_cc[VKILL] = '\0'; ts.c_cc[VEOF] = '\0'; ts.c_cc[VTIME] = '\0'; ts.c_cc[VMIN] = 1; ts.c_cc[VSWTC] = '\0'; ts.c_cc[VSTART] = '\0'; ts.c_cc[VSTOP] = '\0'; ts.c_cc[VSUSP] = '\0'; ts.c_cc[VEOL] = '\0'; ts.c_cc[VREPRINT] = '\0'; ts.c_cc[VDISCARD] = '\0'; ts.c_cc[VWERASE] = '\0'; ts.c_cc[VLNEXT] = '\0'; ts.c_cc[VEOL2] = '\0'; /* Sets the new terminal parameters. */ if (ioctl(fd, TCSETS, &ts) != 0) fatal(ERR_IOCTL); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -