📄 xcterm.c
字号:
/* xcterm.c -- terminal mode module for XC This file uses 4-character tabstops*/#define XCTERM_C 1#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <ctype.h>#include <signal.h>#include <setjmp.h>#include <sys/wait.h>#include <errno.h>#include "xc.h"#if XC_PLUS# include "xctolu.h"# define vtspecial(c) ((((c)>0xaf)&&((c)<0xe0)) ? 1 : 0 )# define vtclear(c) (((c)=='\014') ? 1 : 0 ) /* FORM FEED */#endifchar captfile[SM_BUFF] = CAPTFILE; /* capture file's name */char phonefile[SM_BUFF] = PHFILE; /* phone number file's name */char ddsname[SM_BUFF];FILE *cfp; /* capture file pointer */static FILE *fp; /* file to transmit */static jmp_buf rtm, stop;static RETSIGTYPE (*oldvec)();short s_flag, capture = FALSE;extern short autoflag, nl2cr;extern get_bound_char();/* start capturing */static RETSIGTYPE capt_on(junk)int junk;{ if (capture) sprintf(Msg, "Already capturing to \"%s\"", captfile); else { if (!(cfp = fopen(captfile, "a"))) sprintf(Msg,"Can't open \"%s\" for capturing",captfile); else capture = TRUE, sprintf(Msg,"Capturing to \"%s\"",captfile), setbuf(cfp, NIL(char)); } S2(Msg); signal(SIGUSR1, capt_on); /* set signal for next capt_on */}/* stop capturing */static RETSIGTYPE capt_off(junk)int junk;{ if (!capture) sprintf(Msg,"Sorry, we haven't been capturing lately"); else fclose(cfp), capture = FALSE, sprintf(Msg,"\"%s\" closed for capturing",captfile); S2(Msg); signal(SIGUSR2, capt_off); /* set signal for next capt_off */}/* cleanup, flush and exit */static RETSIGTYPE cleanup(junk)int junk;{ if (capture) fclose(cfp), sprintf(Msg,"\"%s\" closed for capturing",captfile), S2(Msg); exit(0);}static RETSIGTYPE cisbmode(junk)int junk;{ cismode = 2; signal(SIGCHLD, SIG_IGN); longjmp(rtm,1);}static void end_divert(junk)int junk;{ show_abort(); fclose(fp); signal(SIGINT, oldvec); longjmp(stop,1);}/* Divert file into input stream, with delay after each newline. */void divert(script)short script;{ int c; static long i ; if (!script) { prompt_user("File?"); getline(); getword(); } if (word[0] == '\0') return; if (!(fp = fopen(word, "r"))){ sprintf(Msg,"Can't access '%s'",word); S2(Msg); return; } oldvec = signal(SIGINT,end_divert); if (setjmp(stop)) return; i = 1L ; while ((c = getc(fp)) != EOF){ if (c != '\n') sendbyte(c), i++; else { sendbyte(nl2cr ? '\r' : '\n'); /*i = (CBAUD-cbaud)*80 + 4*i + 50;*/ /* season to taste... */ i *= 3; if (script) k_waitfor(-i, ""); else msecs(i); i = 1; } } fclose(fp); signal(SIGINT,oldvec);}/* Select a script file. */static intget_script(){ fputc('\r',tfp), fputc('\n',tfp); show(-1,"Enter script file:"); fputc(' ',tfp); getline(); if (line[0] == '\0'){ fputc('\r',tfp), fputc('\n',tfp); S1("Script file not specified"); return FAILURE; } linkflag = FALSE; getword(); sprintf(ddsname,"%s",word); return SUCCESS;}static pid_t child_pid = 0 ; /* ID of child process */void terminal(todir)short todir;{ register c = 0 ; short doneyet_dd = FALSE; int retcode;#if XC_PLUS int auto_zm_flag = FALSE; unsigned auto_zm_index = 1; const char auto_zm_string[] = "**\030B00800000"; extern char line[], *lptr ; lptr = line ;#endifReterm: if (setjmp(rtm) || doneyet_dd) return; mode(NEWMODE); s_flag = FALSE; /* reset scripting flag */ if (!todir) sprintf(Msg, "Entering TERMINAL mode - Escape character is '%s'", unctrl(my_escape)), S2(Msg); /* split into read and write processes */ if ((child_pid = forkem()) == 0){ /* child, read proc: read from port and write to tty */ cfp = NIL(FILE); if (autoflag && !todir) capt_on(0); signal(SIGUSR1, capt_on); signal(SIGUSR2, capt_off); signal(SIGTERM, cleanup); while (1){ while ((c = readbyte(RB_BLOCK)) == -1) ; if (cismode && c == ENQ) cleanup(0);#if XC_PLUS if ( dosmode ) { /* trap msdos ANSI clear screen escape sequence */ if ( c=='\033') { /* escape character */ fputc( '\033', tfp) ; while ((c = readbyte(RB_BLOCK)) == -1) ; fputc( c , tfp) ; if ( c == '[' ){ while ((c = readbyte(RB_BLOCK)) == -1) ; fputc( c , tfp ); if ( c == '2' ){ while ((c = readbyte(RB_BLOCK)) == -1) ; fputc( c , tfp ); if ( c == 'J' ){ fputc( c , tfp ); cls(); } } } } else if ( vtspecial(c) ) { /* translate msdos "high-ascii" line graphics */#if HAVE_VT102 fputc( '\016', tfp ) ; /* enable line graphics */ fputc( codevt[ (unsigned) c ] , tfp ) ; fputc( '\017' , tfp) ; /* disable line graphics */#else fputc( codevt[ (unsigned) c ] , tfp ) ;#endif } else if ( vtclear(c) ) /* clear screen */ cls(); else /* translate msdos set to latin1 set */ fputc( codelu[ (unsigned) c ] , tfp ) ; } else /* no translation */ fputc(c,tfp); /* auto zmodem starts here: */ if (auto_zm) { if (auto_zm_flag) { if (c != auto_zm_string[auto_zm_index++]) { if( auto_zm_index != 7 || c != '0' ) auto_zm_flag = FALSE; } else if (auto_zm_index == strlen(auto_zm_string)) { do { c = readbyte(RB_BLOCK); /* get rest of string */ if( c != -1 ) putc( c, tfp ); } while ( c != '\r'); putc( '\n', tfp ); auto_zm_flag = FALSE; show(2,"<< ZMODEM Autodownload >>"); strcpy(word,"$\0"); /* let s_shell know we need to redirect the modem */ strcpy(lptr,rzcmd); if ( (retcode = s_shell()) == 1 ) { show(2,"<< ZMODEM Download Failed! >>"); sleep(1); beep(); } else { show(2,"<< ZMODEM Download succeded! >>"); beep(); beep(); beep(); } } } else if (c == auto_zm_string[0]) { auto_zm_flag = TRUE; auto_zm_index = 1; } }#else /*XC_PLUS*/ fputc(c,tfp);#endif if (capture && c != '\r') fputc(c,cfp); } /*NOTREACHED*/ } /* parent, write proc: read from tty and write to port */ if (cismode) signal(SIGCHLD, cisbmode); if (todir) goto dialdir; do { switch (c = get_bound_char()){ case CAPTYES: /* signal child to open capture file */ kill(child_pid, SIGUSR1); break; case CAPTEND: /* signal child to close capture file */ kill(child_pid, SIGUSR2); break; case DIVCHAR: /* divert a file through modem port */ mode(SIGMODE); divert(FALSE); mode(NEWMODE); break; case BRKCHAR: xmitbrk(); break; case HLPCHAR: show_bindings(); break; case SCRPCHR: /* execute a script file */ if (get_script()==FAILURE) break; /* fall through... */ case DOSCRPT: /* named script file */ s_flag = TRUE; goto filicide; case DIALCHR: /* select and dial a phone number */dialdir: doneyet_dd = TRUE; if ((dial_dir()==FAILURE && todir) || s_flag) goto filicide; break; case ENDCHAR: /* signal child to cleanup and exit */filicide: c = ENDCHAR; signal(SIGCHLD, SIG_IGN); kill(child_pid, SIGTERM); break; case QUITCHR: signal(SIGCHLD, SIG_IGN); kill(child_pid, SIGTERM); s_exit(0); /*NOTREACHED*/ break; case HUPCHAR: /* Hangup */ hangup(); break; case CLRGRAF: /* Turn off line graphics and attributes */ reset_crt(); break; case SENDCAN: /* send string of CAN (^X) to stop transfer */ canit(); break; case '\n': /* See if NL translation in effect */ if (nl2cr) c = '\r';#if XC_PLUS case '\177': /* Echo rubout as control H */ if (c!='\r' && c != '\n' && delmode ) c = '\b' ; #endif default: /* just send the character to the port */#if HALF_DUPLEX if (hdplxflag) /* half duplex flag */ fputc(c,tfp);#endif#if XC_PLUS if( dosmode ) /* translate to msdos character set */ c = codepc[ (unsigned) c ] ; #endif sendbyte(c); break; } todir = FALSE; } while (c != ENDCHAR); waitpid(child_pid,&retcode,0); /* wait for the read process to die */ reset_crt(); /* clear line graphics mode and attributes */ if (s_flag){ mode(SIGMODE); do_script(ddsname); goto Reterm; } reterm = FALSE;}#undef XCTERM_C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -