xtmain.c
上传用户:duobangkj
上传日期:2007-01-07
资源大小:70k
文件大小:11k
- /* xtmain.c -- main module for XT
- This file uses 4-character tabstops
- */
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <signal.h>
- #include <ctype.h>
- #include <termio.h>
- #include <setjmp.h>
- #include "xt.h"
- #define Resume_Not_Allowed 1
- short
- autoflag = FALSE, /* Automatic capturing */
- cismode = FALSE, /* Automatic response to CIS "ENQ" */
- cr_add = TRUE, /* Add cr to nl in B+ uploads */
- menuflag = TRUE, /* Show mini-menu */
- nl2cr = TRUE, /* Map nl to cr when transmitting ASCII */
- reterm = FALSE, /* Jump into terminal mode */
- statflag = FALSE, /* Flag for status display */
- eofflag = FALSE; /* Flag to quit a script */
- int s_cis(), s_set(), s_exit(), s_shell();
- char Msg[80], directory[128], hostname[40], ddsname[SM_BUFF];
- unchar BS, LK;
- FILE *tfp;
- struct termio newmode, oldmode, sigmode;
- static char *statfmt = "rtt%-8s %25s %srn",
- version[]="@(#)XT 1.2 JPRadley 8 July 1997",
- oldshell[SM_BUFF],
- *babble[] = {
- "rnUsage: xt [-n site] | [-s file]",
- "t-n sitetSitename to contact with telnet",
- "t-s scripttExecute 'script' immediately",
- NIL(char)
- };
- static s_script(), s_term(), s_help(), s_host(),
- SET_cr(), SET_cis(), SET_nl(), SET_xcape(),
- SET_menu(), SET_autocapt(), SET_cfile(), SET_dir();
- extern short scriptflag;
- extern int sfd;
- extern void B_Transfer(), dbglog(), sattach(), get_ttype();
- jmp_buf erret; /* non-local error return */
- struct kw { /* Used by command parsing routines */
- char *keyword;
- int (*rtn)();
- };
- static struct kw cmds[] = {
- {"c", s_cis},
- {"cis", s_cis},
- {"n", s_host},
- {"nethost", s_host},
- {"s", s_script},
- {"script", s_script},
- {"t", s_term},
- {"term", s_term},
- {"bindings",show_bindings},
- {"set", s_set},
- {"q", s_exit},
- {"quit", s_exit},
- {"exit", s_exit},
- {"x", s_exit},
- {"!", s_shell},
- {"!!", s_shell},
- {"$", s_shell},
- {"~", s_shell},
- {"help", s_help},
- {"?", s_help},
- {NIL(char), 0}
- };
- static struct kw setlist[] = {
- {"auto", SET_autocapt},
- {"cfile", SET_cfile},
- {"cis", SET_cis},
- {"cr", SET_cr},
- {"dir", SET_dir},
- {"menu", SET_menu},
- {"nl", SET_nl},
- {"escape", SET_xcape},
- {"xcape", SET_xcape},
- {NIL(char), 0}
- };
- /* Print the status of the program */
- static void
- status()
- {
- struct kw *ptr;
- char p[40];
- int (*fct)() = 0;
- statflag = TRUE;
- cls();
- cur_off();
- if (*hostname)
- sprintf(p," Telnet => %s",hostname);
- else
- p[0]=' ';
- drawline(0, 0, CO);
- sprintf(Msg,"%s%s",&version[4], p);
- ttgoto(1,(CO-(int)strlen(Msg))/2 -1);
- S1(Msg);
- drawline(2, 0, CO);
- ttgoto(3, 0);
- fprintf(tfp, statfmt, "Keyword", "Description", "Status");
- fprintf(tfp, statfmt,"--------","-------------------------","-----------");
- for (ptr = setlist; ptr->keyword; ptr++)
- if (ptr->rtn != fct){
- fct = ptr->rtn;
- (*fct)();
- }
- ttgoto(14, 25);
- S1("Type "help" or ? for help");
- statflag = FALSE;
- cur_on();
- }
- /* Catch a signal and jump to main. Reset signal and do a longjmp */
- static RETSIGTYPE
- catch(junk)
- int junk;
- {
- if (! isatty(2))
- s_exit();
- S2("XT: Interrupt");
- signal(SIGINT,catch);
- signal(SIGQUIT,catch);
- longjmp(erret,1);
- }
- static void
- usage()
- {
- char **ptr;
- for (ptr = babble; *ptr; ptr++)
- fprintf(tfp, "%srn", *ptr);
- }
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *script = NIL(char);
- extern char *optarg;
- int c;
- extern int optind;
- struct kw *ptr;
- tfp = stderr;
- if (isatty(2))
- get_ttype();
- ioctl(0, TCGETA, &oldmode); /* get current tty mode */
- /* trap for SIGHUP and SIGTERM, make sure LCKfile gets killed */
- signal(SIGHUP,(RETSIGTYPE (*)())s_exit);
- signal(SIGTERM,(RETSIGTYPE (*)())s_exit);
- newmode = oldmode;
- newmode.c_iflag &= ~(IXON | IXOFF | IXANY);
- newmode.c_lflag &= ~(ICANON | ISIG | ECHO);
- newmode.c_oflag = OPOST | ONLCR;
- newmode.c_cc[VMIN] = 1;
- newmode.c_cc[VTIME] = 1;
- BS = newmode.c_cc[VERASE];
- LK = newmode.c_cc[VKILL];
- mode(NEWMODE);
- sigmode = newmode;
- sigmode.c_lflag |= ISIG;
- oldshell[0] = ' '; /* set last command to blank */
- if (setjmp(erret)) /* set error handler to exit */
- exit(0); /* while parsing command line */
- signal(SIGINT,catch); /* catch break & quit signals/keys */
- signal(SIGQUIT,catch);
- default_bindings();
- while ((c = getopt(argc, argv, "s:n:")) != -1)
- switch (c){
- case 's': /* Execute SCRIPT file */
- script = optarg;
- break;
- case 'n': /* network connection using telnet */
- sprintf(hostname,"%s",optarg);
- break;
- default: /* Bad command .. print help */
- usage();
- mode(OLDMODE);
- exit(1);
- }
- getcwd(directory, 64);
- do_script(STARTUP);
- #if LOG
- dbglog();
- #endif
- if (!script)
- status();
- for (;;){
- setjmp(erret);
- signal(SIGQUIT,(RETSIGTYPE (*)())s_exit);
- mode(SIGMODE);
- if (script)
- do_script(script),
- reterm = TRUE,
- script = NIL(char);
- if (sfd < 0 && *hostname)
- reterm = xttn();
- if (reterm && sfd > 0 && isatty(2)){
- s_term();
- continue;
- }
- reterm = FALSE;
- fputc('r',tfp),
- fputc('n',tfp);
- if (menuflag)
- fputc('t',tfp),
- S1("[t]erminal mode [q]uit [s]cript [?]help");
- show(-1,"<XT>");
- fputc(' ',tfp);
- lptr = line;
- getline();
- fputc('r',tfp),
- fputc('n',tfp);
- getword();
- lc_word(word);
- if (word[0] == ' ') /* If blank line... reprompt */
- continue;
- for (ptr = cmds; ptr->keyword; ptr++)
- if (!strcmp(word, ptr->keyword))
- break;
- if (ptr->keyword)
- (*ptr->rtn)();
- else
- sprintf(Msg,"Unrecognized command: %s",word),
- S;
- }
- }
- static
- s_script()
- {
- getword();
- if (word[0] == ' '){
- S1("Script file not specified");
- return;
- }
- sprintf(ddsname,"%s",word);
- do_script(ddsname);
- reterm = TRUE;
- }
- static
- s_host()
- {
- getword();
- if (word[0] == ' '){
- S1("Hostname not specified");
- return;
- }
- sprintf(hostname,"%s",word);
- reterm = xttn();
- }
- static
- s_term()
- {
- reterm = tnterm();
- if (cismode != 2)
- return;
- cismode = 1;
- s_cis();
- }
- s_cis()
- {
- mode(SIGMODE);
- B_Transfer();
- }
- s_shell()
- {
- int stat_loc = 0;
- char c = word[0];
- static char *shell = NIL(char);
- RETSIGTYPE (*oldvec)();
- #if NOSHELL
- return(0);
- #endif
- if (word[0] == word[1])
- strcpy(wptr = word, oldshell);
- else {
- getword();
- if (*wptr)
- strcpy(oldshell, wptr);
- }
- if (!shell){
- shell = getenv("SHELL");
- if (!shell)
- shell = "/bin/sh";
- }
- #if 0
- fputc('r',tfp),
- fputc('n',tfp);
- #endif
- mode(OLDMODE);
- if (!forkem()){
- if (c == '$') /* Attach modem to stdin, stdout */
- sattach();
- signal(SIGCLD,SIG_DFL);
- signal(SIGINT,SIG_DFL);
- signal(SIGQUIT,SIG_DFL);
- if (word[0] == ' ')
- execl(shell, shell, "-i", NIL(char));
- else
- execl(shell, shell, "-c", wptr, NIL(char));
- S1("Exec failed!");
- exit(2);
- }
- oldvec = signal(SIGINT,SIG_IGN);
- wait(&stat_loc);
- signal(SIGINT,oldvec);
- strcpy(oldshell, wptr);
- return(!!stat_loc);
- }
- static char *cmdlist[] = {
- "tXT Command Summary",
- "",
- "tc",
- "tcisttInitiate CIS B+ File Transfer (Upload and Download)",
- "",
- "tx",
- "tq",
- "texit",
- "tquitttExit XT",
- "",
- "tsetttDisplay XT parameters",
- "tset kwttDisplay XT parameter for 'kw'",
- "tset kw valtSet XT keyword 'kw' to 'val'",
- "",
- "tn host",
- "tnethost hosttTelnet to 'host'",
- "",
- "ts file",
- "tscript filetExecute XT script 'file'",
- "",
- #if !NOSHELL
- "t!ttExecute a local interactive shell",
- "t! cmdttExecute shell command string on the local system",
- "t!!ttRe-execute the last shell command string",
- "",
- "t$ cmdttShell command with stdin and stdout redirected to modem",
- "",
- #endif
- "tt",
- "ttermttEnter Terminal mode",
- "",
- "t?",
- "thelpttPrint (this) help text",
- "",
- "tSET Keywords:",
- "",
- "tsettttDisplay current XT status",
- "",
- "tset auto on|offttSet|Unset automatic capturing",
- "",
- "tset cfile namettChange name of capture file",
- "",
- "tset cis onttSet CIS <ENQ> mode (Auto up/download)",
- "tset cis offttDo not respond to <ENQ>",
- "",
- "tset cr on|offttSet|Unset Carriage Return Injection mode",
- "",
- "tset dir namettChange current directory",
- "",
- "tset xcape char",
- "tset escape charttSet the Terminal mode escape character",
- "",
- "tset menu on|offttDo|Don't show mini-menu before XT prompt",
- "",
- "tset nl on|offttSet|Unset newline translation",
- "",
- "",
- NIL(char) };
- static
- s_help()
- {
- char **ptr = cmdlist;
- int curline = 0;
- mode(OLDMODE);
- cls();
- cur_off();
- for ( ; *ptr; ptr++) {
- if (**ptr != '') {
- if (curline >= LI-2){
- S0("PRESS ENTER");
- getline();
- cls();
- curline = 0;
- }
- fprintf(tfp, "%srn", *ptr);
- curline++;
- } else {
- S0("PRESS ENTER");
- getline();
- cls();
- curline = 0;
- }
- }
- show_bindings();
- S0("PRESS ENTER");
- getline();
- cls();
- status();
- }
- s_set()
- {
- struct kw *ptr;
- getword();
- if (word[0] == ' ' && !scriptflag){
- status();
- return;
- } else if (word[0] == ' '){
- S1("SET keyword requires an argument");
- eofflag++;
- return;
- }
- lc_word(word);
- for (ptr = setlist; ptr->keyword; ptr++)
- if (!strcmp(ptr->keyword, word)){
- (*ptr->rtn)();
- return;
- }
- sprintf(Msg,"Invalid SET keyword: %s", word);
- S;
- eofflag++;
- }
- void
- set_onoff(flag)
- short *flag;
- {
- char *ptr = strdup(word);
- uc_word(ptr);
- getword();
- lc_word(word);
- if (!strcmp(word, "on"))
- *flag = TRUE;
- else if (!strcmp(word, "off"))
- *flag = FALSE;
- else
- sprintf(Msg,"Set '%s' value must be 'on' or 'off'",ptr),
- S,
- eofflag++;
- free(ptr);
- }
- static
- SET_dir()
- {
- if (statflag){
- fprintf(tfp, statfmt, "dir", "We are in", directory);
- return;
- }
- getword();
- strcpy(directory, word);
- if (chdir(directory))
- sprintf(Msg,"Can't move to %s", directory),
- S;
- if (!scriptflag)
- sprintf(Msg, "We are in %s", directory),
- S;
- }
- static
- SET_cr()
- {
- if (statflag){
- fprintf(tfp, statfmt, "cr", "Carriage Return Injection",
- cr_add ? "ON" : "OFF");
- return;
- }
- set_onoff(&cr_add);
- if (!scriptflag)
- sprintf(Msg,"Carriage Returns %s injected in B+ ASCII uploads",
- cr_add ? "ARE" : "are NOT"),
- S;
- }
- static
- SET_xcape()
- {
- if (statflag) {
- fprintf(tfp, statfmt, "xcape", "Terminal Escape Character",
- unctrl(my_escape));
- return;
- }
- getword();
- if (word[0] == ' ') {
- show(1,"Set ESCAPE must specify escape character");
- eofflag++;
- return;
- }
- my_escape = word[0];
- if (!scriptflag)
- sprintf(Msg,"Terminal mode escape character set to '%s'",
- unctrl(my_escape)),
- S;
- }
- static
- SET_nl()
- {
- if (statflag){
- fprintf(tfp, statfmt, "nl", "Newline Translation",
- nl2cr ? "ON" : "OFF");
- return;
- }
- set_onoff(&nl2cr);
- if (!scriptflag)
- sprintf(Msg,"Newlines %s changed to Carriage Returns",
- nl2cr ? "ARE" : "are NOT"),
- S;
- }
- static
- SET_cis()
- {
- if (statflag){
- fprintf(tfp, statfmt, "cis", "CIS <ENQ> Auto Download",
- cismode ? "ON" : "OFF");
- return;
- }
- set_onoff(&cismode);
- if (!scriptflag)
- sprintf(Msg,"CIS <ENQ> Auto Download is %s", cismode ? "ON" : "OFF"),
- S;
- }
- static
- SET_menu()
- {
- if (statflag){
- fprintf(tfp, statfmt, "menu", "Mini-menu mode",
- menuflag ? "ON" : "OFF");
- return;
- }
-
- set_onoff(&menuflag);
-
- if (!scriptflag)
- sprintf(Msg,"Mini-menu is %s shown", menuflag ? "" : "NOT"),
- S;
- }
- static
- SET_autocapt()
- {
- if (statflag){
- fprintf(tfp, statfmt, "auto", "Auto Capture",
- autoflag ? "ON" : "OFF");
- return;
- }
- set_onoff(&autoflag);
- if (!scriptflag)
- sprintf(Msg,"Auto Capture is %s", autoflag ? "ON" : "OFF"),
- S;
- }
- static
- SET_cfile()
- {
- if (statflag){
- fprintf(tfp, statfmt, "cfile", "Capture File", captfile);
- return;
- }
- getword();
- if (word[0] == ' '){
- S1("Set CFILE must have file name");
- eofflag++;
- return;
- }
- strcpy(captfile, word);
- if (!scriptflag)
- sprintf(Msg,"Capture file set to '%s'",captfile),
- S;
- }
- s_exit()
- {
- signal(SIGHUP,SIG_IGN);
- signal(SIGINT,SIG_IGN);
- signal(SIGQUIT,SIG_IGN);
- signal(SIGTERM,SIG_IGN);
- mode(OLDMODE);
- exit(0);
- }