xref: /freebsd/usr.bin/talk/io.c (revision 7880fc113fcdf97f2278dd0711dd48d8d8ceed8a)
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