📄 x_ascii.c
字号:
/* * Transfer a file using just XON/XOFF flow control. Currently limited to * 7 bit ASCII codes. (If this causes too much trouble, I'll change it). */#include <stdio.h>#include <curses.h>#include <signal.h>#include "config.h"#include "misc.h"#include "param.h"#ifdef BSD#include <setjmp.h>jmp_buf bl_buf;#endif /* BSD */static void send_ascii(), rcv_ascii(), putc_ascii();static int bgetc_line(), buf_read();voidxfer_ascii(list, up)char *list;int up;{ int cr_lf; char *file, *strtok(); void line_set(), st_line(); void ascii_mode(), term_mode(); unsigned int sleep(); touchwin(stdscr); refresh(); /* only one file from list */ file = strtok(list, " \t"); cr_lf = !strcmp(param->cr_out, "CR/LF"); ascii_mode(up); /* out of curses mode */ resetterm(); term_mode(); tty_noblock(0, TRUE); if (up) send_ascii(file, cr_lf); else rcv_ascii(file, cr_lf); /* * Restoring the TTY modes is easier than setting them... The * fixterm() and line_set() routines fix most of the damage. */ line_set(); fixterm(); tty_noblock(0, FALSE); beep(); st_line("xfer complete"); sleep(2); return;}/* * Send a file. The local echo option is independent of the duplex option, * and would very rarely be used since the characters are most likely * being echoed on the screen anyway. */static voidsend_ascii(file, cr_lf)char *file;int cr_lf;{ extern int fd; FILE *fp, *uid_fopen(); int i, j, strip_cr, strip_lf, add_cr, add_lf, expand, local_echo, pace; char buf[80], c, last; unsigned int sleep(); void error_win(); /* permission already checked */ if (!(fp = uid_fopen(file, "r"))) { sprintf(buf, "\"%s\"", file); error_win(0, "Can't open file for read", buf); return; } /* ASCII transfer options */ strip_cr = !strcmp(param->cr_up, "STRIP"); add_lf = !strcmp(param->cr_up, "ADD LF"); strip_lf = !strcmp(param->lf_up, "STRIP"); add_cr = !strcmp(param->lf_up, "ADD CR"); expand = !strcmp(param->expand, "YES"); local_echo = !strcmp(param->local_echo, "YES"); pace = !strcmp(param->pace, "YES"); last = 0; while ((i = fgetc(fp)) != EOF) { /* any keyboard activity? */ switch (j = getchar()) { case -1: /* no key was pressed */ break; case ESC: /* <ESC> key for abort */ fclose(fp); sleep(2); tty_drain(fd); return; default: /* send the char */ c = (char) j & 0x7f; putc_ascii(c, local_echo); if (c == '\r' && cr_lf) putc_ascii('\n', local_echo); break; } c = (char) i & 0x7f; /* expand blank lines */ if (expand && last == '\n' && c == '\n') putc_ascii(' ', local_echo); last = c; /* CR translations */ if (c == '\r' && strip_cr) continue; if (c == '\r' && add_lf) { putc_ascii(c, local_echo); putc_ascii('\n', local_echo); continue; } /* LF translations */ if (c == '\n' && strip_lf) continue; if (c == '\n' && add_cr) putc_ascii('\r', local_echo); putc_ascii(c, local_echo); /* * There's really no mechanism for delaying characters * going to the output, so we fake it by waiting for * each character to clear the I/O buffer. */ if (pace) tty_drain(fd); } fclose(fp); sleep(2); tty_drain(fd); return;}/* Put a character on the line, echo it too, if required */static voidputc_ascii(c, local_echo)char c;int local_echo;{ extern int fd; void vs_putchar(); write(fd, &c, 1); if (local_echo) { write(1, &c, 1); vs_putchar(c); } return;}/* * Receive a file. The timer is used to end the transfer. This is not * that much different from the data logging option. The use of bgetc_line() * and non-blocking input makes it seem like full duplex, but it's not. * Be aware that while the timer is active the keyboard is deaf. */static voidrcv_ascii(file, cr_lf)char *file;int cr_lf;{ FILE *fp, *uid_fopen(); int i, strip_cr, strip_lf, add_cr, add_lf, got_first; unsigned int delay; char c, buf[80]; void error_win(), vs_putchar(); /* permission already checked */ if (!(fp = uid_fopen(file, "w"))) { sprintf(buf, "\"%s\"", file); error_win(0, "Can't open file for write", buf); return; } /* ASCII transfer options */ strip_cr = !strcmp(param->cr_dn, "STRIP"); add_lf = !strcmp(param->cr_dn, "ADD LF"); strip_lf = !strcmp(param->lf_dn, "STRIP"); add_cr = !strcmp(param->lf_dn, "ADD CR"); got_first = 0; delay = 1; /* CONSTCOND */ while (1) { /* keyboard activity */ switch (i = getchar()) { case -1: /* no key was pressed */ break; case ESC: /* <ESC> key */ fclose(fp); return; default: /* send it */ c = (unsigned int) i; putc_line((unsigned char) c); if (c == '\r' && cr_lf) putc_line('\n'); break; } /* read a character */ if ((i = bgetc_line(delay)) == -1) { /* * The transfer timeout is not activated until the * first character is received. Until then, it polls * the line for one second and loops backs for * keyboard input. */ if (got_first) { fclose(fp); return; } continue; } got_first = 1; delay = param->timer; c = i & 0x7f; /* display it on the screen */ write(1, &c, 1); vs_putchar(c); /* CR translations */ if (c == '\r' && strip_cr) continue; if (c == '\r' && add_lf) { fputc(c, fp); fputc('\n', fp); continue; } /* LF translations */ if (c == '\n' && strip_lf) continue; if (c == '\n' && add_cr) { fputc('\r', fp); fputc(c, fp); continue; } fputc(c, fp); }}/* * Get a character from the line (using buffered I/O) with a specified * time-out period in seconds. If the function times-out, it returns a -1. */static int bl_flag;static int bl_force();static intbgetc_line(sec)unsigned int sec;{ int c; unsigned int alarm(); signal(SIGALRM, (SIG_TYPE(*) ()) bl_force); bl_flag = 0; alarm(sec);#ifdef BSD if (setjmp(bl_buf)) return(-1);#endif /* BSD */ if ((c = buf_read()) < 0) { alarm(0); return(-1); } if (bl_flag) return(-1); alarm(0); return(c);}/* ARGSUSED */static intbl_force(dummy)int dummy;{#ifdef BSD longjmp(bl_buf, 1);#else /* BSD */ signal(SIGALRM, (SIG_TYPE(*) ()) bl_force); bl_flag = 1; return(0);#endif /* BSD */}/* * Do a single character buffered read from the serial port. */static intbuf_read(){ extern int fd; static char buf[CLIST_SIZ]; static char *bufp = buf; static int n = 0; if (n <= 0) { n = read(fd, buf, CLIST_SIZ); bufp = buf; } if (--n >= 0) return(*bufp++ & 0xff); return(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -