This is xcterm.c in view mode; [Download] [Up]
/* xcterm.c -- terminal mode module for XC This file uses 4-character tabstops */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #include <signal.h> #include <setjmp.h> #if defined(NEXT) #include <termios.h> #else #include <termio.h> #endif #include "xc.h" char captfile[SM_BUFF] = CAPTFILE, /* capture file's name */ phonefile[SM_BUFF] = PHFILE, /* phone number file's name */ ddsname[SM_BUFF]; FILE *cfp; /* capture file pointer */ static FILE *fp; /* file to transmit */ static pid_t child_pid; /* ID of child process */ 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(SIGCLD, 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; long i = 1; if (!script) fputc('\r',tfp), fputc('\n',tfp), show(-1,"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; 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 get_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; } void terminal(todir) short todir; { register c; short doneyet_dd = FALSE; Reterm: 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'", #if defined(NEXT) xc_unctrl(my_escape)), #else unctrl(my_escape)), #endif 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(0)) == -1) ; if (cismode && c == ENQ) cleanup(0); fputc(c,tfp); if (capture && c != '\r') fputc(c,cfp); } /*NOTREACHED*/ } /* parent, write proc: read from tty and write to port */ if (cismode) signal(SIGCLD, 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(SIGCLD, SIG_IGN); kill(child_pid, SIGTERM); break; case QUITCHR: signal(SIGCLD, SIG_IGN); kill(child_pid, SIGTERM); s_exit(); break; case HUPCHAR: /* Hangup */ hangup(); break; case '\n': /* See if NL translation in effect */ if (nl2cr) c = '\r'; default: /* just send the character to the port */ sendbyte(c); break; } todir = FALSE; } while (c != ENDCHAR); while (wait(NIL(int)) >= 0) /* wait for the read process to die */ ; if (s_flag){ mode(SIGMODE); do_script(ddsname); goto Reterm; } reterm = FALSE; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.