11590Srgrimes/* 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 3087710Smarkm#include <sys/cdefs.h> 3187710Smarkm 3287710Smarkm__FBSDID("$FreeBSD$"); 3387710Smarkm 341590Srgrimes#ifndef lint 3587710Smarkmstatic const char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; 3632503Scharnier#endif 371590Srgrimes 381590Srgrimes/* 398874Srgrimes * This file contains the I/O handling and the exchange of 401590Srgrimes * edit characters. This connection itself is established in 411590Srgrimes * ctl.c 421590Srgrimes */ 431590Srgrimes 4487710Smarkm#include <sys/filio.h> 4587710Smarkm 461590Srgrimes#include <errno.h> 47128445Scognet#include <signal.h> 4881346Sdd#include <netdb.h> 4981346Sdd#include <stdlib.h> 501590Srgrimes#include <string.h> 5180381Ssheldonh#include <unistd.h> 5287710Smarkm 531590Srgrimes#include "talk.h" 5481346Sdd#include "talk_ctl.h" 551590Srgrimes 561590Srgrimes#define A_LONG_TIME 10000000 571590Srgrimes 58128445Scognetvolatile sig_atomic_t gotwinch = 0; 59128445Scognet 601590Srgrimes/* 611590Srgrimes * The routine to do the actual talking 621590Srgrimes */ 6314443Sjoergvoid 64178642Sdelphijtalk(void) 651590Srgrimes{ 6681346Sdd struct hostent *hp, *hp2; 6714443Sjoerg int nb; 6814443Sjoerg fd_set read_set, read_template; 6981346Sdd char buf[BUFSIZ], **addr, *his_machine_name; 701590Srgrimes struct timeval wait; 711590Srgrimes 7281346Sdd his_machine_name = NULL; 7381346Sdd hp = gethostbyaddr((const char *)&his_machine_addr.s_addr, 7481346Sdd sizeof(his_machine_addr.s_addr), AF_INET); 7581346Sdd if (hp != NULL) { 7681346Sdd hp2 = gethostbyname(hp->h_name); 7781346Sdd if (hp2 != NULL && hp2->h_addrtype == AF_INET && 7881346Sdd hp2->h_length == sizeof(his_machine_addr)) 7981346Sdd for (addr = hp2->h_addr_list; *addr != NULL; addr++) 8081346Sdd if (memcmp(*addr, &his_machine_addr, 8181346Sdd sizeof(his_machine_addr)) == 0) { 8281346Sdd his_machine_name = strdup(hp->h_name); 8381346Sdd break; 8481346Sdd } 8581346Sdd } 8681346Sdd if (his_machine_name == NULL) 8781346Sdd his_machine_name = strdup(inet_ntoa(his_machine_addr)); 8881346Sdd snprintf(buf, sizeof(buf), "Connection established with %s@%s.", 8981346Sdd msg.r_name, his_machine_name); 9081346Sdd free(his_machine_name); 9181346Sdd message(buf); 9217676Speter write(STDOUT_FILENO, "\007\007\007", 3); 9317676Speter 941590Srgrimes current_line = 0; 951590Srgrimes 961590Srgrimes /* 978874Srgrimes * Wait on both the other process (sockt_mask) and 981590Srgrimes * standard input ( STDIN_MASK ) 991590Srgrimes */ 10014443Sjoerg FD_ZERO(&read_template); 10114443Sjoerg FD_SET(sockt, &read_template); 10214443Sjoerg FD_SET(fileno(stdin), &read_template); 1031590Srgrimes for (;;) { 1041590Srgrimes read_set = read_template; 1051590Srgrimes wait.tv_sec = A_LONG_TIME; 1061590Srgrimes wait.tv_usec = 0; 1071590Srgrimes nb = select(32, &read_set, 0, 0, &wait); 108128445Scognet if (gotwinch) { 109128445Scognet resize_display(); 110128445Scognet gotwinch = 0; 111128445Scognet } 1121590Srgrimes if (nb <= 0) { 1131590Srgrimes if (errno == EINTR) { 1141590Srgrimes read_set = read_template; 1151590Srgrimes continue; 1161590Srgrimes } 1171590Srgrimes /* panic, we don't know what happened */ 1181590Srgrimes p_error("Unexpected error from select"); 1191590Srgrimes quit(); 1201590Srgrimes } 12114443Sjoerg if (FD_ISSET(sockt, &read_set)) { 1221590Srgrimes /* There is data on sockt */ 1231590Srgrimes nb = read(sockt, buf, sizeof buf); 1241590Srgrimes if (nb <= 0) { 1251590Srgrimes message("Connection closed. Exiting"); 1261590Srgrimes quit(); 1271590Srgrimes } 1281590Srgrimes display(&his_win, buf, nb); 1291590Srgrimes } 13014443Sjoerg if (FD_ISSET(fileno(stdin), &read_set)) { 1311590Srgrimes /* 1321590Srgrimes * We can't make the tty non_blocking, because 1331590Srgrimes * curses's output routines would screw up 1341590Srgrimes */ 13562932Sps int i; 136120549Stjr ioctl(0, FIONREAD, (void *) &nb); 137178642Sdelphij if (nb > (ssize_t)(sizeof buf)) 138129090Scognet nb = sizeof buf; 13980381Ssheldonh nb = read(STDIN_FILENO, buf, nb); 1401590Srgrimes display(&my_win, buf, nb); 1411590Srgrimes /* might lose data here because sockt is non-blocking */ 14262932Sps for (i = 0; i < nb; ++i) 14362932Sps if (buf[i] == '\r') 14462932Sps buf[i] = '\n'; 1451590Srgrimes write(sockt, buf, nb); 1461590Srgrimes } 1471590Srgrimes } 1481590Srgrimes} 1491590Srgrimes 1501590Srgrimes/* 1511590Srgrimes * p_error prints the system error message on the standard location 1521590Srgrimes * on the screen and then exits. (i.e. a curses version of perror) 1531590Srgrimes */ 15414443Sjoergvoid 155178642Sdelphijp_error(const char *string) 1561590Srgrimes{ 1577451Sache wmove(my_win.x_win, current_line, 0); 1581590Srgrimes wprintw(my_win.x_win, "[%s : %s (%d)]\n", 1591590Srgrimes string, strerror(errno), errno); 1601590Srgrimes wrefresh(my_win.x_win); 1611590Srgrimes move(LINES-1, 0); 1621590Srgrimes refresh(); 1631590Srgrimes quit(); 1641590Srgrimes} 1651590Srgrimes 1661590Srgrimes/* 1671590Srgrimes * Display string in the standard location 1681590Srgrimes */ 16914443Sjoergvoid 170178642Sdelphijmessage(const char *string) 1711590Srgrimes{ 1727451Sache wmove(my_win.x_win, current_line, 0); 1737451Sache wprintw(my_win.x_win, "[%s]\n", string); 1747451Sache if (current_line < my_win.x_nlines - 1) 1757451Sache current_line++; 1761590Srgrimes wrefresh(my_win.x_win); 1771590Srgrimes} 178