/* On SIGTSTP, we restore the tty mode to the origanal. * On SIGCONT, we restore it, and the stdio fd flags, to what we hade before * the suspend. */ static void stop_handler(int signum) { struct termios mine; int need_tty_reset; int stdin_flags; int stdout_flags; int stderr_flags; assert(signum == SIGTSTP); stdin_flags = fcntl(STDIN_FILENO, F_GETFL); stdout_flags = fcntl(STDOUT_FILENO, F_GETFL); stderr_flags = fcntl(STDERR_FILENO, F_GETFL); need_tty_reset = (tty_fd > 0) ? tty_getattr(tty_fd, &mine) : 0; if (need_tty_reset) tty_setattr(tty_fd, &original_mode); #ifndef MACOS kill(getpid(), SIGSTOP); #endif if (need_tty_reset) tty_setattr(tty_fd, &mine); if (stdin_flags >= 0) fcntl(STDIN_FILENO, F_SETFL, stdin_flags); if (stdout_flags >= 0) fcntl(STDOUT_FILENO, F_SETFL, stdin_flags); if (stderr_flags >= 0) fcntl(STDERR_FILENO, F_SETFL, stdin_flags); }
int tty_open(char *port,int speed) { int rc,fd; tty_hangedup=0; tty_port=xstrdup(port); if(tty_lock(port))return ME_CANTLOCK; DEBUG(('M',3,"tty_open")); fflush(stdin);fflush(stdout); setbuf(stdin,NULL);setbuf(stdout,NULL); close(STDIN_FILENO);close(STDOUT_FILENO); fd=open(port,O_RDONLY|O_NONBLOCK); if(dup2(fd,STDIN_FILENO)!=STDIN_FILENO)return ME_OPEN; if(fd!=STDIN_FILENO)close(fd); fd=open(port,O_WRONLY|O_NONBLOCK); if(dup2(fd,STDOUT_FILENO)!=STDOUT_FILENO)return ME_OPEN; if(fd!=STDOUT_FILENO)close(fd); clearerr(stdin);clearerr(stdout); rc=tty_setattr(speed); if(rc)return rc; return tty_block(1); }
static void answer_mode(int type) { int rc, spd;char *cs; struct sockaddr_in sa; socklen_t ss=sizeof(sa); sts_t sts; if(cfgs(CFG_ROOTDIR)&&ccs[0])chdir(ccs); rnode=xcalloc(1,sizeof(ninfo_t)); is_ip=!isatty(0); xstrcpy(ip_id,"ipline",10); rnode->tty=xstrdup(is_ip?(bink?"binkp":"tcpip"):basename(ttyname(0))); rnode->options|=O_INB; if(!log_init(cfgs(CFG_LOG),rnode->tty)) { printf("can't open log %s!\n",ccs); exit(S_FAILURE); } signal(SIGINT,SIG_IGN); signal(SIGTERM,sigerr); signal(SIGSEGV,sigerr); signal(SIGFPE,sigerr); signal(SIGPIPE,SIG_IGN); IFPerl(perl_init(cfgs(CFG_PERLFILE),0)); log_callback=NULL;xsend_cb=NULL; ssock=cls_conn(CLS_LINE,cfgs(CFG_SERVER),NULL); if(ssock<0)write_log("can't connect to server: %s",strerror(errno)); else log_callback=vlogs; rc=aso_init(cfgs(CFG_ASOOUTBOUND),cfgs(CFG_BSOOUTBOUND),cfgs(CFG_QSTOUTBOUND),cfgal(CFG_ADDRESS)->addr.z); if(!rc) { write_log("No outbound defined"); stopit(S_FAILURE); } write_log("answering incoming call");vidle(); if(is_ip&&!getpeername(0,(struct sockaddr*)&sa,&ss)) { write_log("remote is %s",inet_ntoa(sa.sin_addr)); spd=TCP_SPEED; } else { cs=getenv("CONNECT");spd=cs?atoi(cs):0; xfree(connstr);connstr=xstrdup(cs); if(cs&&spd)write_log("*** CONNECT %s",cs); else { write_log("*** CONNECT Unknown"); spd=DEFAULT_SPEED; } } if((cs=getenv("CALLER_ID"))&&strcasecmp(cs,"none")&&strlen(cs)>3)write_log("caller-id: %s",cs); tty_setattr(0); tty_local(0); rc=session(0,type,NULL,spd); tty_local(1); if(!is_ip) { hangup(); stat_collect(); } tty_cooked(); if((S_OK==(rc&S_MASK))&&cfgi(CFG_HOLDONSUCCESS)) { log_done(); log_init(cfgs(CFG_MASTERLOG),NULL); aso_getstatus(&rnode->addrs->addr, &sts); sts.flags|=(Q_WAITA|Q_WAITR|Q_WAITX); sts.htime=MAX(t_set(cci*60),sts.htime); write_log("calls to %s delayed for %d min after successful incoming session", ftnaddrtoa(&rnode->addrs->addr),cci); aso_setstatus(&rnode->addrs->addr,&sts); log_done(); log_init(cfgs(CFG_LOG),rnode->tty); } title("Waiting..."); vidle();sline(""); aso_done(); stopit(rc); }