/* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #include "tip.h" #include /* * tip * * lower fork of tip -- handles passive side * reading from the remote host */ FILE *fscript; static sigjmp_buf sigbuf; /* * TIPOUT wait state routine -- * sent by TIPIN when it wants to posses the remote host */ void intIOT(void) { (void) write(repdes[1], &ccc, 1); (void) read(fildes[0], &ccc, 1); siglongjmp(sigbuf, 1); } /* * Scripting command interpreter -- * accepts script file name over the pipe and acts accordingly */ void intEMT(void) { char c, line[PATH_MAX]; char *pline = line; char reply; (void) read(fildes[0], &c, 1); while (c != '\n' && line + sizeof (line) - pline > 1) { *pline++ = c; (void) read(fildes[0], &c, 1); } *pline = '\0'; if (boolean(value(SCRIPT)) && fscript != NULL) (void) fclose(fscript); if (pline == line) { boolean(value(SCRIPT)) = FALSE; reply = 'y'; } else { if ((fscript = fopen(line, "a")) == NULL) reply = 'n'; else { reply = 'y'; boolean(value(SCRIPT)) = TRUE; } } (void) write(repdes[1], &reply, 1); siglongjmp(sigbuf, 1); } void intTERM(void) { if (boolean(value(SCRIPT)) && fscript != NULL) (void) fclose(fscript); exit(0); } void intSYS(void) { boolean(value(BEAUTIFY)) = !boolean(value(BEAUTIFY)); siglongjmp(sigbuf, 1); } /* * ****TIPOUT TIPOUT**** */ void tipout(void) { char buf[BUFSIZ]; char *cp; int cnt; sigset_t omask, bmask, tmask; (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); /* attention from TIPIN */ (void) signal(SIGEMT, (sig_handler_t)intEMT); /* time to go signal */ (void) signal(SIGTERM, (sig_handler_t)intTERM); /* scripting going on signal */ (void) signal(SIGIOT, (sig_handler_t)intIOT); /* for dial-ups */ (void) signal(SIGHUP, (sig_handler_t)intTERM); /* beautify toggle */ (void) signal(SIGSYS, (sig_handler_t)intSYS); (void) sigsetjmp(sigbuf, 1); (void) sigemptyset(&omask); (void) sigemptyset(&bmask); (void) sigaddset(&bmask, SIGEMT); (void) sigaddset(&bmask, SIGTERM); (void) sigaddset(&bmask, SIGIOT); (void) sigaddset(&bmask, SIGSYS); (void) sigemptyset(&tmask); (void) sigaddset(&tmask, SIGTERM); for (;;) { cnt = read(FD, buf, BUFSIZ); if (cnt <= 0) { /* * If dialback is specified, ignore the hangup * and clear the hangup condition on the device. */ if (cnt == 0 && DB) { int fd; DB = 0; if ((fd = open(DV, O_RDWR)) >= 0) { if (fd != FD) (void) close(fd); } continue; } /* lost carrier */ if ((cnt < 0 && errno == EIO) || (cnt == 0)) { (void) sigprocmask(SIG_BLOCK, &tmask, NULL); intTERM(); /*NOTREACHED*/ } } else { (void) sigprocmask(SIG_BLOCK, &bmask, &omask); if (!noparity) for (cp = buf; cp < buf + cnt; cp++) *cp &= 0177; (void) write(1, buf, cnt); if (boolean(value(SCRIPT)) && fscript != NULL) { if (!boolean(value(BEAUTIFY))) { (void) fwrite(buf, 1, cnt, fscript); } else { for (cp = buf; cp < buf + cnt; cp++) if ((*cp >= ' ' && *cp <= '~')|| any(*cp, value(EXCEPTIONS))) (void) putc(*cp, fscript); } } } (void) sigprocmask(SIG_SETMASK, &omask, NULL); } }