home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
s
/
seyon197.tz
/
seyon197
/
seyon
/
SeTerm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-16
|
5KB
|
229 lines
/*
* This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
* Saggaf. All rights reserved.
*
* See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
* statement of rights and permissions for this program.
*/
/*
* This file contains routines for Seyon's terminal. The main routine is
* terminal(), which reads characters from the terminal and sends them to the
* port. That routine also forks a child process that reads characters from
* the port and writes them to the temrinal. Once the parent receives SIGTERM
* (which should be sent by the grand parent), it kills the child and exits.
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <X11/Intrinsic.h>
#include "seyon.h"
#include "SeDecl.h"
extern int readStr();
extern FILE *tfp, /* terminal pointer */
*cfp; /* capture file pointer */
extern Boolean capture; /* are we capturing or not ? */
void send_tbyte(),
toggle(),
cleanup();
pid_t term_pid = 0, /* pid of the terminal subprocess */
read_pid = 0; /* pid of child process */
void
term_exit(dummy)
int dummy;
{
/* Once the signal is received and we're outside the loop, disable catching
the signal */
signal(SIGTERM, SIG_IGN);
/* Kill the child process and wait for it to die, sounds vicious,
doesn't it? The child process is the read process from the port */
if (read_pid) {
kill(read_pid, SIGTERM);
while (wait((int *)0) >= 0);
}
exit(0);
}
/*
* main routine. has two processes one to read from terminal and send to the
* port and the other to do the oppsite.
*/
void
terminal()
{
/* Tell the program where to go when SIGTERM is received */
signal(SIGTERM, term_exit);
term_pid = getpid();
/* Split into read and write processes */
/* Child, read proc: read from port and write to tty */
if ((read_pid = se_fork()) == 0)
PortToTty();
/* Parent, write proc: read from tty and write to port */
while (1)
send_tbyte(coninp());
}
/*
* send a translated character to the modem
*/
void
send_tbyte(c)
int c;
{
switch (c) {
/*Translate new line to carriage return if newline translation mode is
in effect*/
case '\n':
switch (newlineTrMode) {
case 2:
c = '\r';
break;
case 3:
sendbyte('\r');
default:
break;
}
break;
/*Translate backspace to delete if del translation mode is in effect*/
case 0x08:
if (qres.backspaceTranslation)
c = 0x7f;
break;
default:
break;
}
/*Send ESC before the character if meta key is pressed with the character
and the meta key translation mode is on*/
if (qres.metaKeyTranslation && (c & 0x80)) {
sendbyte('\033');
sendbyte(c);
}
/*Send the character to the port*/
else
sendbyte(c);
}
/*
* Cleanup, flush and exit
*/
void
cleanup()
{
fflush(tfp);
exit(0);
}
/*
* Read from the port and write to the tty
*/
void
PortToTty()
{
static char zmSig[] = "**\030B00";
static char *zmSigPtr = zmSig;
char buf[BUFSIZ], c;
int n, i;
signal(SIGTERM, cleanup);
while (1) {
/* Read incoming charaters and exit the process if a read error
is encountered */
if ((n = readStr(buf)) < 0) {
se_error("Read error. Terminal process exiting");
se_notice("Use REFRESH to restart");
write_child_info(child_pipe, KILL_TERM, "Terminal Proc Exited");
exit(0);
}
/* Write incoming characters to the tty */
fwrite(buf, sizeof(char), n, tfp);
fflush(tfp);
for(i = 0; i < n; i++) {
c = buf[i];
/* Write to capture file if capture is enabled */
if (capture /*&& c != '\r'*/)
fputc(c, cfp);
/* Look for Zmodem signature */
if (c != *zmSigPtr)
zmSigPtr = zmSig;
else if (*++zmSigPtr == '\0' && qres.zmodemAutoDownload) {
write_child_info(child_pipe, START_AUTO_ZM, "Zmodem Auto-Download");
exit(0);
}
} /* for... */
} /* while(1)... */
/*NOT REACHED*/
}
/*
* Start the terminal process
*/
void
start_terminal()
{
if (!term_pid)
if ((term_pid = se_fork()) == 0) {
terminal();
exit(0);
}
}
/*
* Kill the terminal process
*/
void
kill_terminal()
{
if (term_pid) {
kill(term_pid, SIGTERM);
/*Wait for the child to die*/
wait((int *)0);
term_pid = 0;
}
}
/*
* Restart the terminal process (refresh) by killing it and starting a new
* one
*/
void
restart_terminal()
{
kill_terminal();
start_terminal();
}