xref: /freebsd/usr.bin/talk/io.c (revision 8a16b7a18f5d0b031f09832fd7752fba717e2a97)
1*8a16b7a1SPedro F. Giffuni /*-
2*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
3*8a16b7a1SPedro F. Giffuni  *
49b50d902SRodney W. Grimes  * Copyright (c) 1983, 1993
59b50d902SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
69b50d902SRodney W. Grimes  *
79b50d902SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
89b50d902SRodney W. Grimes  * modification, are permitted provided that the following conditions
99b50d902SRodney W. Grimes  * are met:
109b50d902SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
119b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
129b50d902SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
139b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
149b50d902SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
169b50d902SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
179b50d902SRodney W. Grimes  *    without specific prior written permission.
189b50d902SRodney W. Grimes  *
199b50d902SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
209b50d902SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
219b50d902SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
229b50d902SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
239b50d902SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
249b50d902SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
259b50d902SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
269b50d902SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
279b50d902SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
289b50d902SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
299b50d902SRodney W. Grimes  * SUCH DAMAGE.
309b50d902SRodney W. Grimes  */
319b50d902SRodney W. Grimes 
32caa64801SMark Murray #include <sys/cdefs.h>
33caa64801SMark Murray 
34caa64801SMark Murray __FBSDID("$FreeBSD$");
35caa64801SMark Murray 
369b50d902SRodney W. Grimes #ifndef lint
37caa64801SMark Murray static const char sccsid[] = "@(#)io.c	8.1 (Berkeley) 6/6/93";
3820868061SPhilippe Charnier #endif
399b50d902SRodney W. Grimes 
409b50d902SRodney W. Grimes /*
419b50d902SRodney W. Grimes  * This file contains the I/O handling and the exchange of
429b50d902SRodney W. Grimes  * edit characters. This connection itself is established in
439b50d902SRodney W. Grimes  * ctl.c
449b50d902SRodney W. Grimes  */
459b50d902SRodney W. Grimes 
46caa64801SMark Murray #include <sys/filio.h>
47caa64801SMark Murray 
489b50d902SRodney W. Grimes #include <errno.h>
49ec8ffccbSOlivier Houchard #include <signal.h>
50e896c344SDima Dorfman #include <netdb.h>
517880fc11SPedro F. Giffuni #include <poll.h>
5205b0160eSGleb Smirnoff #include <stdio.h>
53e896c344SDima Dorfman #include <stdlib.h>
549b50d902SRodney W. Grimes #include <string.h>
55e1b4d8d0SSheldon Hearn #include <unistd.h>
5605b0160eSGleb Smirnoff #define _XOPEN_SOURCE_EXTENDED
5705b0160eSGleb Smirnoff #include <curses.h>
58caa64801SMark Murray 
599b50d902SRodney W. Grimes #include "talk.h"
60e896c344SDima Dorfman #include "talk_ctl.h"
619b50d902SRodney W. Grimes 
6205b0160eSGleb Smirnoff extern void	display(xwin_t *, wchar_t *);
639b50d902SRodney W. Grimes 
64ec8ffccbSOlivier Houchard volatile sig_atomic_t gotwinch = 0;
65ec8ffccbSOlivier Houchard 
669b50d902SRodney W. Grimes /*
679b50d902SRodney W. Grimes  * The routine to do the actual talking
689b50d902SRodney W. Grimes  */
6928592604SJoerg Wunsch void
70b6d9e1f3SXin LI talk(void)
719b50d902SRodney W. Grimes {
72e896c344SDima Dorfman 	struct hostent *hp, *hp2;
737880fc11SPedro F. Giffuni 	struct pollfd fds[2];
7428592604SJoerg Wunsch 	int nb;
7505b0160eSGleb Smirnoff 	wchar_t buf[BUFSIZ];
7605b0160eSGleb Smirnoff 	char **addr, *his_machine_name;
7705b0160eSGleb Smirnoff 	FILE *sockfp;
789b50d902SRodney W. Grimes 
79e896c344SDima Dorfman 	his_machine_name = NULL;
80e896c344SDima Dorfman 	hp = gethostbyaddr((const char *)&his_machine_addr.s_addr,
81e896c344SDima Dorfman 	    sizeof(his_machine_addr.s_addr), AF_INET);
82e896c344SDima Dorfman 	if (hp != NULL) {
83e896c344SDima Dorfman 		hp2 = gethostbyname(hp->h_name);
84e896c344SDima Dorfman 		if (hp2 != NULL && hp2->h_addrtype == AF_INET &&
85e896c344SDima Dorfman 		    hp2->h_length == sizeof(his_machine_addr))
86e896c344SDima Dorfman 			for (addr = hp2->h_addr_list; *addr != NULL; addr++)
87e896c344SDima Dorfman 				if (memcmp(*addr, &his_machine_addr,
88e896c344SDima Dorfman 				    sizeof(his_machine_addr)) == 0) {
89e896c344SDima Dorfman 					his_machine_name = strdup(hp->h_name);
90e896c344SDima Dorfman 					break;
91e896c344SDima Dorfman 				}
92e896c344SDima Dorfman 	}
93e896c344SDima Dorfman 	if (his_machine_name == NULL)
94e896c344SDima Dorfman 		his_machine_name = strdup(inet_ntoa(his_machine_addr));
9505b0160eSGleb Smirnoff 	snprintf((char *)buf, sizeof(buf), "Connection established with %s@%s.",
96e896c344SDima Dorfman 	    msg.r_name, his_machine_name);
97e896c344SDima Dorfman 	free(his_machine_name);
9805b0160eSGleb Smirnoff 	message((char *)buf);
99e151ec23SPeter Wemm 	write(STDOUT_FILENO, "\007\007\007", 3);
100e151ec23SPeter Wemm 
1019b50d902SRodney W. Grimes 	current_line = 0;
1029b50d902SRodney W. Grimes 
10305b0160eSGleb Smirnoff 	if ((sockfp = fdopen(sockt, "w+")) == NULL)
10405b0160eSGleb Smirnoff 		p_error("fdopen");
10505b0160eSGleb Smirnoff 
10605b0160eSGleb Smirnoff 	setvbuf(sockfp, NULL, _IONBF, 0);
10705b0160eSGleb Smirnoff 	setvbuf(stdin, NULL, _IONBF, 0);
10805b0160eSGleb Smirnoff 
1099b50d902SRodney W. Grimes 	/*
11005b0160eSGleb Smirnoff 	 * Wait on both the other process (sockt) and standard input.
1119b50d902SRodney W. Grimes 	 */
1129b50d902SRodney W. Grimes 	for (;;) {
1137880fc11SPedro F. Giffuni 		fds[0].fd = fileno(stdin);
1147880fc11SPedro F. Giffuni 		fds[0].events = POLLIN;
1157880fc11SPedro F. Giffuni 		fds[1].fd = sockt;
1167880fc11SPedro F. Giffuni 		fds[1].events = POLLIN;
1177880fc11SPedro F. Giffuni 		nb = poll(fds, 2, INFTIM);
118ec8ffccbSOlivier Houchard 		if (gotwinch) {
119ec8ffccbSOlivier Houchard 			resize_display();
120ec8ffccbSOlivier Houchard 			gotwinch = 0;
121ec8ffccbSOlivier Houchard 		}
1229b50d902SRodney W. Grimes 		if (nb <= 0) {
12305b0160eSGleb Smirnoff 			if (errno == EINTR)
1249b50d902SRodney W. Grimes 				continue;
12505b0160eSGleb Smirnoff 			/* Panic, we don't know what happened. */
1267880fc11SPedro F. Giffuni 			p_error("Unexpected error from poll");
1279b50d902SRodney W. Grimes 			quit();
1289b50d902SRodney W. Grimes 		}
1297880fc11SPedro F. Giffuni 		if (fds[1].revents & POLLIN) {
13005b0160eSGleb Smirnoff 			wint_t w;
13105b0160eSGleb Smirnoff 
13205b0160eSGleb Smirnoff 			/* There is data on sockt. */
13305b0160eSGleb Smirnoff 			w = fgetwc(sockfp);
13405b0160eSGleb Smirnoff 			if (w == WEOF) {
1359b50d902SRodney W. Grimes 				message("Connection closed. Exiting");
1369b50d902SRodney W. Grimes 				quit();
1379b50d902SRodney W. Grimes 			}
13805b0160eSGleb Smirnoff 			display(&his_win, &w);
1399b50d902SRodney W. Grimes 		}
1407880fc11SPedro F. Giffuni 		if (fds[0].revents & POLLIN) {
14105b0160eSGleb Smirnoff 			wint_t w;
14205b0160eSGleb Smirnoff 
14305b0160eSGleb Smirnoff 			if ((w = getwchar()) != WEOF) {
14405b0160eSGleb Smirnoff 				display(&my_win, &w);
14505b0160eSGleb Smirnoff 				(void )fputwc(w, sockfp);
14605b0160eSGleb Smirnoff 				(void )fflush(sockfp);
14705b0160eSGleb Smirnoff 			}
1489b50d902SRodney W. Grimes 		}
1499b50d902SRodney W. Grimes 	}
1509b50d902SRodney W. Grimes }
1519b50d902SRodney W. Grimes 
1529b50d902SRodney W. Grimes /*
1539b50d902SRodney W. Grimes  * p_error prints the system error message on the standard location
1549b50d902SRodney W. Grimes  * on the screen and then exits. (i.e. a curses version of perror)
1559b50d902SRodney W. Grimes  */
15628592604SJoerg Wunsch void
157b6d9e1f3SXin LI p_error(const char *string)
1589b50d902SRodney W. Grimes {
159b02b5aadSAndrey A. Chernov 	wmove(my_win.x_win, current_line, 0);
1609b50d902SRodney W. Grimes 	wprintw(my_win.x_win, "[%s : %s (%d)]\n",
1619b50d902SRodney W. Grimes 	    string, strerror(errno), errno);
1629b50d902SRodney W. Grimes 	wrefresh(my_win.x_win);
1639b50d902SRodney W. Grimes 	move(LINES-1, 0);
1649b50d902SRodney W. Grimes 	refresh();
1659b50d902SRodney W. Grimes 	quit();
1669b50d902SRodney W. Grimes }
1679b50d902SRodney W. Grimes 
1689b50d902SRodney W. Grimes /*
1699b50d902SRodney W. Grimes  * Display string in the standard location
1709b50d902SRodney W. Grimes  */
17128592604SJoerg Wunsch void
172b6d9e1f3SXin LI message(const char *string)
1739b50d902SRodney W. Grimes {
174b02b5aadSAndrey A. Chernov 	wmove(my_win.x_win, current_line, 0);
175b02b5aadSAndrey A. Chernov 	wprintw(my_win.x_win, "[%s]\n", string);
176b02b5aadSAndrey A. Chernov 	if (current_line < my_win.x_nlines - 1)
1779b50d902SRodney W. Grimes 		current_line++;
1789b50d902SRodney W. Grimes 	wrefresh(my_win.x_win);
1799b50d902SRodney W. Grimes }
180