1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 34 __FBSDID("$FreeBSD$"); 35 36 #ifndef lint 37 static const char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; 38 #endif 39 40 /* 41 * This file contains the I/O handling and the exchange of 42 * edit characters. This connection itself is established in 43 * ctl.c 44 */ 45 46 #include <sys/filio.h> 47 48 #include <errno.h> 49 #include <signal.h> 50 #include <netdb.h> 51 #include <poll.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <unistd.h> 56 #define _XOPEN_SOURCE_EXTENDED 57 #include <curses.h> 58 59 #include "talk.h" 60 #include "talk_ctl.h" 61 62 extern void display(xwin_t *, wchar_t *); 63 64 volatile sig_atomic_t gotwinch = 0; 65 66 /* 67 * The routine to do the actual talking 68 */ 69 void 70 talk(void) 71 { 72 struct hostent *hp, *hp2; 73 struct pollfd fds[2]; 74 int nb; 75 wchar_t buf[BUFSIZ]; 76 char **addr, *his_machine_name; 77 FILE *sockfp; 78 79 his_machine_name = NULL; 80 hp = gethostbyaddr((const char *)&his_machine_addr.s_addr, 81 sizeof(his_machine_addr.s_addr), AF_INET); 82 if (hp != NULL) { 83 hp2 = gethostbyname(hp->h_name); 84 if (hp2 != NULL && hp2->h_addrtype == AF_INET && 85 hp2->h_length == sizeof(his_machine_addr)) 86 for (addr = hp2->h_addr_list; *addr != NULL; addr++) 87 if (memcmp(*addr, &his_machine_addr, 88 sizeof(his_machine_addr)) == 0) { 89 his_machine_name = strdup(hp->h_name); 90 break; 91 } 92 } 93 if (his_machine_name == NULL) 94 his_machine_name = strdup(inet_ntoa(his_machine_addr)); 95 snprintf((char *)buf, sizeof(buf), "Connection established with %s@%s.", 96 msg.r_name, his_machine_name); 97 free(his_machine_name); 98 message((char *)buf); 99 write(STDOUT_FILENO, "\007\007\007", 3); 100 101 current_line = 0; 102 103 if ((sockfp = fdopen(sockt, "w+")) == NULL) 104 p_error("fdopen"); 105 106 setvbuf(sockfp, NULL, _IONBF, 0); 107 setvbuf(stdin, NULL, _IONBF, 0); 108 109 /* 110 * Wait on both the other process (sockt) and standard input. 111 */ 112 for (;;) { 113 fds[0].fd = fileno(stdin); 114 fds[0].events = POLLIN; 115 fds[1].fd = sockt; 116 fds[1].events = POLLIN; 117 nb = poll(fds, 2, INFTIM); 118 if (gotwinch) { 119 resize_display(); 120 gotwinch = 0; 121 } 122 if (nb <= 0) { 123 if (errno == EINTR) 124 continue; 125 /* Panic, we don't know what happened. */ 126 p_error("Unexpected error from poll"); 127 quit(); 128 } 129 if (fds[1].revents & POLLIN) { 130 wint_t w; 131 132 /* There is data on sockt. */ 133 w = fgetwc(sockfp); 134 if (w == WEOF) { 135 message("Connection closed. Exiting"); 136 quit(); 137 } 138 display(&his_win, &w); 139 } 140 if (fds[0].revents & POLLIN) { 141 wint_t w; 142 143 if ((w = getwchar()) != WEOF) { 144 display(&my_win, &w); 145 (void )fputwc(w, sockfp); 146 (void )fflush(sockfp); 147 } 148 } 149 } 150 } 151 152 /* 153 * p_error prints the system error message on the standard location 154 * on the screen and then exits. (i.e. a curses version of perror) 155 */ 156 void 157 p_error(const char *string) 158 { 159 wmove(my_win.x_win, current_line, 0); 160 wprintw(my_win.x_win, "[%s : %s (%d)]\n", 161 string, strerror(errno), errno); 162 wrefresh(my_win.x_win); 163 move(LINES-1, 0); 164 refresh(); 165 quit(); 166 } 167 168 /* 169 * Display string in the standard location 170 */ 171 void 172 message(const char *string) 173 { 174 wmove(my_win.x_win, current_line, 0); 175 wprintw(my_win.x_win, "[%s]\n", string); 176 if (current_line < my_win.x_nlines - 1) 177 current_line++; 178 wrefresh(my_win.x_win); 179 } 180