diff options
author | joerg <joerg@FreeBSD.org> | 1996-03-09 19:23:01 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-03-09 19:23:01 +0000 |
commit | a12cf8aa0e1029b87db1d40e09450d0d09635334 (patch) | |
tree | 05d5824bd651018bd12409c9b3fa9369e6f2c193 /usr.bin/talk | |
parent | 17cc9fc50275a82f4224ba957d768981a45929d7 (diff) | |
download | FreeBSD-src-a12cf8aa0e1029b87db1d40e09450d0d09635334.zip FreeBSD-src-a12cf8aa0e1029b87db1d40e09450d0d09635334.tar.gz |
Make talk automagically find out the interface IP address where the
remote peer will be connected through. This avoids the ``Checking for
invitation on caller's machine'' problem for multi-homed hosts.
Thanks to: Garrett, for his `find_interface' example
Diffstat (limited to 'usr.bin/talk')
-rw-r--r-- | usr.bin/talk/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/talk/ctl.c | 7 | ||||
-rw-r--r-- | usr.bin/talk/ctl_transact.c | 14 | ||||
-rw-r--r-- | usr.bin/talk/display.c | 9 | ||||
-rw-r--r-- | usr.bin/talk/get_addrs.c | 33 | ||||
-rw-r--r-- | usr.bin/talk/get_iface.c | 99 | ||||
-rw-r--r-- | usr.bin/talk/get_names.c | 8 | ||||
-rw-r--r-- | usr.bin/talk/init_disp.c | 11 | ||||
-rw-r--r-- | usr.bin/talk/invite.c | 8 | ||||
-rw-r--r-- | usr.bin/talk/io.c | 18 | ||||
-rw-r--r-- | usr.bin/talk/look_up.c | 3 | ||||
-rw-r--r-- | usr.bin/talk/msgs.c | 6 | ||||
-rw-r--r-- | usr.bin/talk/talk.c | 4 | ||||
-rw-r--r-- | usr.bin/talk/talk.h | 36 |
14 files changed, 207 insertions, 54 deletions
diff --git a/usr.bin/talk/Makefile b/usr.bin/talk/Makefile index 9643a37..c676d5d 100644 --- a/usr.bin/talk/Makefile +++ b/usr.bin/talk/Makefile @@ -1,10 +1,11 @@ # From: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $Id$ +# $Id: Makefile,v 1.3 1995/02/21 04:35:43 wollman Exp $ PROG= talk DPADD= ${LIBCURSES} ${LIBTERMCAP} LDADD= -lcurses -ltermcap -SRCS= ctl.c ctl_transact.c display.c get_addrs.c get_names.c \ +CFLAGS+= -Wall -Wstrict-prototypes -Wno-unused +SRCS= ctl.c ctl_transact.c display.c get_addrs.c get_iface.c get_names.c \ init_disp.c invite.c io.c look_up.c msgs.c talk.c .include <bsd.prog.mk> diff --git a/usr.bin/talk/ctl.c b/usr.bin/talk/ctl.c index 18b0c5c..2f77608 100644 --- a/usr.bin/talk/ctl.c +++ b/usr.bin/talk/ctl.c @@ -64,6 +64,7 @@ int invitation_waiting = 0; CTL_MSG msg; +void open_sockt() { int length; @@ -81,6 +82,7 @@ open_sockt() } /* open the ctl socket */ +void open_ctl() { int length; @@ -100,13 +102,14 @@ open_ctl() } /* print_addr is a debug print routine */ +void print_addr(addr) struct sockaddr_in addr; { int i; - printf("addr = %x, port = %o, family = %o zero = ", - addr.sin_addr, addr.sin_port, addr.sin_family); + printf("addr = %lx, port = %o, family = %o zero = ", + addr.sin_addr.s_addr, addr.sin_port, addr.sin_family); for (i = 0; i<8;i++) printf("%o ", (int)addr.sin_zero[i]); putchar('\n'); diff --git a/usr.bin/talk/ctl_transact.c b/usr.bin/talk/ctl_transact.c index 512e040..2cd4dce 100644 --- a/usr.bin/talk/ctl_transact.c +++ b/usr.bin/talk/ctl_transact.c @@ -35,12 +35,9 @@ static char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <protocols/talkd.h> #include <errno.h> +#include <string.h> +#include "talk.h" #include "talk_ctl.h" #define CTL_WAIT 2 /* time to wait for a response, in seconds */ @@ -50,19 +47,22 @@ static char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) 6/6/93"; * not recieved an acknowledgement within a reasonable amount * of time */ +void ctl_transact(target, msg, type, rp) struct in_addr target; CTL_MSG msg; int type; CTL_RESPONSE *rp; { - int read_mask, ctl_mask, nready, cc; + fd_set read_mask, ctl_mask; + int nready = 0, cc; struct timeval wait; msg.type = type; daemon_addr.sin_addr = target; daemon_addr.sin_port = daemon_port; - ctl_mask = 1 << ctl_sockt; + FD_ZERO(&ctl_mask); + FD_SET(ctl_sockt, &ctl_mask); /* * Keep sending the message until a response of diff --git a/usr.bin/talk/display.c b/usr.bin/talk/display.c index 076c6e1..ed4e5ab 100644 --- a/usr.bin/talk/display.c +++ b/usr.bin/talk/display.c @@ -52,6 +52,7 @@ int curses_initialized = 0; * max HAS to be a function, it is called with * a argument of the form --foo at least once. */ +int max(a,b) int a, b; { @@ -63,9 +64,10 @@ max(a,b) * Display some text on somebody's window, processing some control * characters while we are at it. */ +void display(win, text, size) register xwin_t *win; - register unsigned char *text; + register char *text; int size; { register int i; @@ -150,7 +152,7 @@ display(win, text, size) cch = (*text & 63) + 64; waddch(win->x_win, cch); } else - waddch(win->x_win, *text); + waddch(win->x_win, (unsigned)*text); getyx(win->x_win, win->x_line, win->x_col); text++; } @@ -160,8 +162,11 @@ display(win, text, size) /* * Read the character at the indicated position in win */ +int readwin(win, line, col) WINDOW *win; + int line; + int col; { int oldline, oldcol; register int c; diff --git a/usr.bin/talk/get_addrs.c b/usr.bin/talk/get_addrs.c index b9db4a6..7ac9267 100644 --- a/usr.bin/talk/get_addrs.c +++ b/usr.bin/talk/get_addrs.c @@ -35,14 +35,13 @@ static char sccsid[] = "@(#)get_addrs.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <protocols/talkd.h> +#include <string.h> #include <netdb.h> #include <stdio.h> +#include "talk.h" #include "talk_ctl.h" +void get_addrs(my_machine_name, his_machine_name) char *my_machine_name, *his_machine_name; { @@ -50,28 +49,18 @@ get_addrs(my_machine_name, his_machine_name) struct servent *sp; msg.pid = htonl(getpid()); - /* look up the address of the local host */ - hp = gethostbyname(my_machine_name); + + hp = gethostbyname(his_machine_name); if (hp == NULL) { - fprintf(stderr, "talk: %s: ", my_machine_name); + fprintf(stderr, "talk: %s: ", his_machine_name); herror((char *)NULL); exit(-1); } - bcopy(hp->h_addr, (char *)&my_machine_addr, hp->h_length); - /* - * If the callee is on-machine, just copy the - * network address, otherwise do a lookup... - */ - if (strcmp(his_machine_name, my_machine_name)) { - hp = gethostbyname(his_machine_name); - if (hp == NULL) { - fprintf(stderr, "talk: %s: ", his_machine_name); - herror((char *)NULL); - exit(-1); - } - bcopy(hp->h_addr, (char *) &his_machine_addr, hp->h_length); - } else - his_machine_addr = my_machine_addr; + bcopy(hp->h_addr, (char *) &his_machine_addr, hp->h_length); + if (get_iface(&his_machine_addr, &my_machine_addr) == -1) { + perror("failed to find my interface address"); + exit(-1); + } /* find the server's port */ sp = getservbyname("ntalk", "udp"); if (sp == 0) { diff --git a/usr.bin/talk/get_iface.c b/usr.bin/talk/get_iface.c new file mode 100644 index 0000000..58defdc --- /dev/null +++ b/usr.bin/talk/get_iface.c @@ -0,0 +1,99 @@ +/* + * Copyright 1994, 1995 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: + * Id: find_interface.c,v 1.1 1995/08/14 16:08:39 wollman Exp + * + * $Id$ + */ + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "talk.h" + +/* + * Try to find the interface address that is used to route an IP + * packet to a remote peer. + */ + +int +get_iface(dst, iface) + struct in_addr *dst; + struct in_addr *iface; +{ + static struct sockaddr_in local; + struct sockaddr_in remote; + struct hostent *hp; + int s, rv, namelen; + + memcpy(&remote.sin_addr, dst, sizeof remote.sin_addr); + remote.sin_port = htons(60000); + remote.sin_family = AF_INET; + remote.sin_len = sizeof remote; + + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(60000); + local.sin_family = AF_INET; + local.sin_len = sizeof local; + + s = socket(PF_INET, SOCK_DGRAM, 0); + if (s < 0) + return -1; + + do { + rv = bind(s, (struct sockaddr *)&local, sizeof local); + local.sin_port++; + } while(rv < 0 && errno == EADDRINUSE); + + if (rv < 0) { + close(s); + return -1; + } + + do { + rv = connect(s, (struct sockaddr *)&remote, sizeof remote); + remote.sin_port++; + } while(rv < 0 && errno == EADDRINUSE); + + if (rv < 0) { + close(s); + return -1; + } + + namelen = sizeof local; + rv = getsockname(s, (struct sockaddr *)&local, &namelen); + close(s); + if (rv < 0) + return -1; + + memcpy(iface, &local.sin_addr, sizeof local.sin_addr); + return 0; +} diff --git a/usr.bin/talk/get_names.c b/usr.bin/talk/get_names.c index 0d1fcf1..793ce72 100644 --- a/usr.bin/talk/get_names.c +++ b/usr.bin/talk/get_names.c @@ -35,20 +35,18 @@ static char sccsid[] = "@(#)get_names.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#include <unistd.h> +#include <string.h> #include <sys/param.h> -#include <sys/socket.h> -#include <protocols/talkd.h> #include <pwd.h> #include "talk.h" -char *getlogin(); -char *ttyname(); -char *rindex(); extern CTL_MSG msg; /* * Determine the local and remote user, tty, and machines */ +void get_names(argc, argv) int argc; char *argv[]; diff --git a/usr.bin/talk/init_disp.c b/usr.bin/talk/init_disp.c index e50b9e8..bfcfd94 100644 --- a/usr.bin/talk/init_disp.c +++ b/usr.bin/talk/init_disp.c @@ -53,7 +53,8 @@ static char sccsid[] = "@(#)init_disp.c 8.2 (Berkeley) 2/16/94"; /* * Make sure the callee can write to the screen */ -void check_writeable() +void +check_writeable() { char *tty; struct stat sb; @@ -70,9 +71,9 @@ void check_writeable() * Set up curses, catch the appropriate signals, * and build the various windows. */ +void init_display() { - void sig_sent(); struct sigvec sigv; if (initscr() == NULL) @@ -113,6 +114,7 @@ init_display() * the first three characters each talk transmits after * connection are the three edit characters. */ +void set_edit_chars() { char buf[3]; @@ -142,8 +144,10 @@ set_edit_chars() his_win.werase = buf[2]; } +/* ARGSUSED */ void -sig_sent() +sig_sent(signo) + int signo; { message("Connection closing. Exiting"); @@ -153,6 +157,7 @@ sig_sent() /* * All done talking...hang up the phone and reset terminal thingy's */ +void quit() { diff --git a/usr.bin/talk/invite.c b/usr.bin/talk/invite.c index d7c33f3..579aed0 100644 --- a/usr.bin/talk/invite.c +++ b/usr.bin/talk/invite.c @@ -59,9 +59,9 @@ static char sccsid[] = "@(#)invite.c 8.1 (Berkeley) 6/6/93"; * invitations. */ int local_id, remote_id; -void re_invite(); jmp_buf invitebuf; +void invite_remote() { int nfd, read_mask, template, new_sockt; @@ -117,8 +117,10 @@ invite_remote() /* * Routine called on interupt to re-invite the callee */ +/* ARGSUSED */ void -re_invite() +re_invite(signo) + int signo; { message("Ringing your party again"); @@ -147,6 +149,7 @@ static char *answers[] = { /* * Transmit the invitation and process the response */ +void announce_invite() { CTL_RESPONSE response; @@ -167,6 +170,7 @@ announce_invite() /* * Tell the daemon to remove your invitation */ +void send_delete() { diff --git a/usr.bin/talk/io.c b/usr.bin/talk/io.c index f7f31bd..f608654 100644 --- a/usr.bin/talk/io.c +++ b/usr.bin/talk/io.c @@ -49,28 +49,28 @@ static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; #include "talk.h" #define A_LONG_TIME 10000000 -#define STDIN_MASK (1<<fileno(stdin)) /* the bit mask for standard - input */ /* * The routine to do the actual talking */ +void talk() { - register int read_template, sockt_mask; - int read_set, nb; + int nb; + fd_set read_set, read_template; char buf[BUFSIZ]; struct timeval wait; message("Connection established\007\007\007"); current_line = 0; - sockt_mask = (1<<sockt); /* * Wait on both the other process (sockt_mask) and * standard input ( STDIN_MASK ) */ - read_template = sockt_mask | STDIN_MASK; + FD_ZERO(&read_template); + FD_SET(sockt, &read_template); + FD_SET(fileno(stdin), &read_template); for (;;) { read_set = read_template; wait.tv_sec = A_LONG_TIME; @@ -85,7 +85,7 @@ talk() p_error("Unexpected error from select"); quit(); } - if (read_set & sockt_mask) { + if (FD_ISSET(sockt, &read_set)) { /* There is data on sockt */ nb = read(sockt, buf, sizeof buf); if (nb <= 0) { @@ -94,7 +94,7 @@ talk() } display(&his_win, buf, nb); } - if (read_set & STDIN_MASK) { + if (FD_ISSET(fileno(stdin), &read_set)) { /* * We can't make the tty non_blocking, because * curses's output routines would screw up @@ -115,6 +115,7 @@ extern int sys_nerr; * p_error prints the system error message on the standard location * on the screen and then exits. (i.e. a curses version of perror) */ +void p_error(string) char *string; { @@ -130,6 +131,7 @@ p_error(string) /* * Display string in the standard location */ +void message(string) char *string; { diff --git a/usr.bin/talk/look_up.c b/usr.bin/talk/look_up.c index cc4b4c5..62356ea 100644 --- a/usr.bin/talk/look_up.c +++ b/usr.bin/talk/look_up.c @@ -46,6 +46,7 @@ static char sccsid[] = "@(#)look_up.c 8.1 (Berkeley) 6/6/93"; /* * See if the local daemon has an invitation for us. */ +int check_local() { CTL_RESPONSE response; @@ -89,11 +90,13 @@ check_local() } p_error("Unable to connect with initiator"); /*NOTREACHED*/ + return (0); } /* * Look for an invitation on 'machine' */ +int look_for_invite(rp) CTL_RESPONSE *rp; { diff --git a/usr.bin/talk/msgs.c b/usr.bin/talk/msgs.c index 6e8cc9b..0b3eeee 100644 --- a/usr.bin/talk/msgs.c +++ b/usr.bin/talk/msgs.c @@ -50,12 +50,15 @@ static char sccsid[] = "@(#)msgs.c 8.1 (Berkeley) 6/6/93"; char *current_state; int current_line = 0; +/* ARGSUSED */ void -disp_msg() +disp_msg(signo) + int signo; { message(current_state); } +void start_msgs() { struct itimerval itimer; @@ -67,6 +70,7 @@ start_msgs() setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); } +void end_msgs() { struct itimerval itimer; diff --git a/usr.bin/talk/talk.c b/usr.bin/talk/talk.c index 3add633..68b9d57 100644 --- a/usr.bin/talk/talk.c +++ b/usr.bin/talk/talk.c @@ -59,6 +59,9 @@ static char sccsid[] = "@(#)talk.c 8.1 (Berkeley) 6/6/93"; * Fixed to not run with unwriteable terminals MRVM 28/12/94 */ +int main __P((int, char **)); + +int main(argc, argv) int argc; char *argv[]; @@ -76,4 +79,5 @@ main(argc, argv) end_msgs(); set_edit_chars(); talk(); + return 0; } diff --git a/usr.bin/talk/talk.h b/usr.bin/talk/talk.h index 98a7118..63bd373 100644 --- a/usr.bin/talk/talk.h +++ b/usr.bin/talk/talk.h @@ -33,7 +33,15 @@ * @(#)talk.h 8.1 (Berkeley) 6/6/93 */ +#include <sys/cdefs.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <protocols/talkd.h> #include <curses.h> +#include <unistd.h> extern int sockt; extern int curses_initialized; @@ -56,3 +64,31 @@ typedef struct xwin { extern xwin_t my_win; extern xwin_t his_win; extern WINDOW *line_win; + +extern void announce_invite __P((void)); +extern int check_local __P((void)); +extern void check_writeable __P((void)); +extern void ctl_transact __P((struct in_addr,CTL_MSG,int,CTL_RESPONSE *)); +extern void disp_msg __P((int)); +extern void display __P((xwin_t *, char *, int)); +extern void end_msgs __P((void)); +extern void get_addrs __P((char *, char *)); +extern int get_iface __P((struct in_addr *, struct in_addr *)); +extern void get_names __P((int, char **)); +extern void init_display __P((void)); +extern void invite_remote __P((void)); +extern int look_for_invite __P((CTL_RESPONSE *)); +extern int max __P((int, int)); +extern void message __P((char *)); +extern void open_ctl __P((void)); +extern void open_sockt __P((void)); +extern void p_error __P((char *)); +extern void print_addr __P((struct sockaddr_in)); +extern void quit __P((void)); +extern int readwin __P((WINDOW *, int, int)); +extern void re_invite __P((int)); +extern void send_delete __P((void)); +extern void set_edit_chars __P((void)); +extern void sig_sent __P((int)); +extern void start_msgs __P((void)); +extern void talk __P((void)); |