19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1983, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 149b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 159b50d902SRodney W. Grimes * without specific prior written permission. 169b50d902SRodney W. Grimes * 179b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 189b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 199b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 209b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 219b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 229b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 239b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 249b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 259b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 269b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 279b50d902SRodney W. Grimes * SUCH DAMAGE. 289b50d902SRodney W. Grimes */ 299b50d902SRodney W. Grimes 30caa64801SMark Murray #include <sys/cdefs.h> 31caa64801SMark Murray 32caa64801SMark Murray __FBSDID("$FreeBSD$"); 33caa64801SMark Murray 349b50d902SRodney W. Grimes #ifndef lint 35caa64801SMark Murray static const char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; 3620868061SPhilippe Charnier #endif 379b50d902SRodney W. Grimes 389b50d902SRodney W. Grimes /* 399b50d902SRodney W. Grimes * This file contains the I/O handling and the exchange of 409b50d902SRodney W. Grimes * edit characters. This connection itself is established in 419b50d902SRodney W. Grimes * ctl.c 429b50d902SRodney W. Grimes */ 439b50d902SRodney W. Grimes 44caa64801SMark Murray #include <sys/filio.h> 45caa64801SMark Murray 469b50d902SRodney W. Grimes #include <errno.h> 47ec8ffccbSOlivier Houchard #include <signal.h> 48e896c344SDima Dorfman #include <netdb.h> 49*7880fc11SPedro F. Giffuni #include <poll.h> 5005b0160eSGleb Smirnoff #include <stdio.h> 51e896c344SDima Dorfman #include <stdlib.h> 529b50d902SRodney W. Grimes #include <string.h> 53e1b4d8d0SSheldon Hearn #include <unistd.h> 5405b0160eSGleb Smirnoff #define _XOPEN_SOURCE_EXTENDED 5505b0160eSGleb Smirnoff #include <curses.h> 56caa64801SMark Murray 579b50d902SRodney W. Grimes #include "talk.h" 58e896c344SDima Dorfman #include "talk_ctl.h" 599b50d902SRodney W. Grimes 6005b0160eSGleb Smirnoff extern void display(xwin_t *, wchar_t *); 619b50d902SRodney W. Grimes 62ec8ffccbSOlivier Houchard volatile sig_atomic_t gotwinch = 0; 63ec8ffccbSOlivier Houchard 649b50d902SRodney W. Grimes /* 659b50d902SRodney W. Grimes * The routine to do the actual talking 669b50d902SRodney W. Grimes */ 6728592604SJoerg Wunsch void 68b6d9e1f3SXin LI talk(void) 699b50d902SRodney W. Grimes { 70e896c344SDima Dorfman struct hostent *hp, *hp2; 71*7880fc11SPedro F. Giffuni struct pollfd fds[2]; 7228592604SJoerg Wunsch int nb; 7305b0160eSGleb Smirnoff wchar_t buf[BUFSIZ]; 7405b0160eSGleb Smirnoff char **addr, *his_machine_name; 7505b0160eSGleb Smirnoff FILE *sockfp; 769b50d902SRodney W. Grimes 77e896c344SDima Dorfman his_machine_name = NULL; 78e896c344SDima Dorfman hp = gethostbyaddr((const char *)&his_machine_addr.s_addr, 79e896c344SDima Dorfman sizeof(his_machine_addr.s_addr), AF_INET); 80e896c344SDima Dorfman if (hp != NULL) { 81e896c344SDima Dorfman hp2 = gethostbyname(hp->h_name); 82e896c344SDima Dorfman if (hp2 != NULL && hp2->h_addrtype == AF_INET && 83e896c344SDima Dorfman hp2->h_length == sizeof(his_machine_addr)) 84e896c344SDima Dorfman for (addr = hp2->h_addr_list; *addr != NULL; addr++) 85e896c344SDima Dorfman if (memcmp(*addr, &his_machine_addr, 86e896c344SDima Dorfman sizeof(his_machine_addr)) == 0) { 87e896c344SDima Dorfman his_machine_name = strdup(hp->h_name); 88e896c344SDima Dorfman break; 89e896c344SDima Dorfman } 90e896c344SDima Dorfman } 91e896c344SDima Dorfman if (his_machine_name == NULL) 92e896c344SDima Dorfman his_machine_name = strdup(inet_ntoa(his_machine_addr)); 9305b0160eSGleb Smirnoff snprintf((char *)buf, sizeof(buf), "Connection established with %s@%s.", 94e896c344SDima Dorfman msg.r_name, his_machine_name); 95e896c344SDima Dorfman free(his_machine_name); 9605b0160eSGleb Smirnoff message((char *)buf); 97e151ec23SPeter Wemm write(STDOUT_FILENO, "\007\007\007", 3); 98e151ec23SPeter Wemm 999b50d902SRodney W. Grimes current_line = 0; 1009b50d902SRodney W. Grimes 10105b0160eSGleb Smirnoff if ((sockfp = fdopen(sockt, "w+")) == NULL) 10205b0160eSGleb Smirnoff p_error("fdopen"); 10305b0160eSGleb Smirnoff 10405b0160eSGleb Smirnoff setvbuf(sockfp, NULL, _IONBF, 0); 10505b0160eSGleb Smirnoff setvbuf(stdin, NULL, _IONBF, 0); 10605b0160eSGleb Smirnoff 1079b50d902SRodney W. Grimes /* 10805b0160eSGleb Smirnoff * Wait on both the other process (sockt) and standard input. 1099b50d902SRodney W. Grimes */ 1109b50d902SRodney W. Grimes for (;;) { 111*7880fc11SPedro F. Giffuni fds[0].fd = fileno(stdin); 112*7880fc11SPedro F. Giffuni fds[0].events = POLLIN; 113*7880fc11SPedro F. Giffuni fds[1].fd = sockt; 114*7880fc11SPedro F. Giffuni fds[1].events = POLLIN; 115*7880fc11SPedro F. Giffuni nb = poll(fds, 2, INFTIM); 116ec8ffccbSOlivier Houchard if (gotwinch) { 117ec8ffccbSOlivier Houchard resize_display(); 118ec8ffccbSOlivier Houchard gotwinch = 0; 119ec8ffccbSOlivier Houchard } 1209b50d902SRodney W. Grimes if (nb <= 0) { 12105b0160eSGleb Smirnoff if (errno == EINTR) 1229b50d902SRodney W. Grimes continue; 12305b0160eSGleb Smirnoff /* Panic, we don't know what happened. */ 124*7880fc11SPedro F. Giffuni p_error("Unexpected error from poll"); 1259b50d902SRodney W. Grimes quit(); 1269b50d902SRodney W. Grimes } 127*7880fc11SPedro F. Giffuni if (fds[1].revents & POLLIN) { 12805b0160eSGleb Smirnoff wint_t w; 12905b0160eSGleb Smirnoff 13005b0160eSGleb Smirnoff /* There is data on sockt. */ 13105b0160eSGleb Smirnoff w = fgetwc(sockfp); 13205b0160eSGleb Smirnoff if (w == WEOF) { 1339b50d902SRodney W. Grimes message("Connection closed. Exiting"); 1349b50d902SRodney W. Grimes quit(); 1359b50d902SRodney W. Grimes } 13605b0160eSGleb Smirnoff display(&his_win, &w); 1379b50d902SRodney W. Grimes } 138*7880fc11SPedro F. Giffuni if (fds[0].revents & POLLIN) { 13905b0160eSGleb Smirnoff wint_t w; 14005b0160eSGleb Smirnoff 14105b0160eSGleb Smirnoff if ((w = getwchar()) != WEOF) { 14205b0160eSGleb Smirnoff display(&my_win, &w); 14305b0160eSGleb Smirnoff (void )fputwc(w, sockfp); 14405b0160eSGleb Smirnoff (void )fflush(sockfp); 14505b0160eSGleb Smirnoff } 1469b50d902SRodney W. Grimes } 1479b50d902SRodney W. Grimes } 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes 1509b50d902SRodney W. Grimes /* 1519b50d902SRodney W. Grimes * p_error prints the system error message on the standard location 1529b50d902SRodney W. Grimes * on the screen and then exits. (i.e. a curses version of perror) 1539b50d902SRodney W. Grimes */ 15428592604SJoerg Wunsch void 155b6d9e1f3SXin LI p_error(const char *string) 1569b50d902SRodney W. Grimes { 157b02b5aadSAndrey A. Chernov wmove(my_win.x_win, current_line, 0); 1589b50d902SRodney W. Grimes wprintw(my_win.x_win, "[%s : %s (%d)]\n", 1599b50d902SRodney W. Grimes string, strerror(errno), errno); 1609b50d902SRodney W. Grimes wrefresh(my_win.x_win); 1619b50d902SRodney W. Grimes move(LINES-1, 0); 1629b50d902SRodney W. Grimes refresh(); 1639b50d902SRodney W. Grimes quit(); 1649b50d902SRodney W. Grimes } 1659b50d902SRodney W. Grimes 1669b50d902SRodney W. Grimes /* 1679b50d902SRodney W. Grimes * Display string in the standard location 1689b50d902SRodney W. Grimes */ 16928592604SJoerg Wunsch void 170b6d9e1f3SXin LI message(const char *string) 1719b50d902SRodney W. Grimes { 172b02b5aadSAndrey A. Chernov wmove(my_win.x_win, current_line, 0); 173b02b5aadSAndrey A. Chernov wprintw(my_win.x_win, "[%s]\n", string); 174b02b5aadSAndrey A. Chernov if (current_line < my_win.x_nlines - 1) 1759b50d902SRodney W. Grimes current_line++; 1769b50d902SRodney W. Grimes wrefresh(my_win.x_win); 1779b50d902SRodney W. Grimes } 178