summaryrefslogtreecommitdiffstats
path: root/usr.bin/talk
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-03-09 19:23:01 +0000
committerjoerg <joerg@FreeBSD.org>1996-03-09 19:23:01 +0000
commita12cf8aa0e1029b87db1d40e09450d0d09635334 (patch)
tree05d5824bd651018bd12409c9b3fa9369e6f2c193 /usr.bin/talk
parent17cc9fc50275a82f4224ba957d768981a45929d7 (diff)
downloadFreeBSD-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/Makefile5
-rw-r--r--usr.bin/talk/ctl.c7
-rw-r--r--usr.bin/talk/ctl_transact.c14
-rw-r--r--usr.bin/talk/display.c9
-rw-r--r--usr.bin/talk/get_addrs.c33
-rw-r--r--usr.bin/talk/get_iface.c99
-rw-r--r--usr.bin/talk/get_names.c8
-rw-r--r--usr.bin/talk/init_disp.c11
-rw-r--r--usr.bin/talk/invite.c8
-rw-r--r--usr.bin/talk/io.c18
-rw-r--r--usr.bin/talk/look_up.c3
-rw-r--r--usr.bin/talk/msgs.c6
-rw-r--r--usr.bin/talk/talk.c4
-rw-r--r--usr.bin/talk/talk.h36
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));
OpenPOWER on IntegriCloud