386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 01:15:27 +0000 (17:15 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 01:15:27 +0000 (17:15 -0800)
Work on file usr/src/usr.bin/talk/ctl.c
Work on file usr/src/usr.bin/talk/ctl_transact.c
Work on file usr/src/usr.bin/talk/get_addrs.c
Work on file usr/src/usr.bin/talk/display.c
Work on file usr/src/usr.bin/talk/get_names.c
Work on file usr/src/usr.bin/talk/init_disp.c
Work on file usr/src/usr.bin/talk/look_up.c
Work on file usr/src/usr.bin/talk/io.c
Work on file usr/src/usr.bin/talk/invite.c
Work on file usr/src/usr.bin/talk/msgs.c
Work on file usr/src/usr.bin/talk/talk.c
Work on file usr/src/usr.bin/talk/talk.h
Work on file usr/src/usr.bin/talk/talk_ctl.h

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

13 files changed:
usr/src/usr.bin/talk/ctl.c [new file with mode: 0644]
usr/src/usr.bin/talk/ctl_transact.c [new file with mode: 0644]
usr/src/usr.bin/talk/display.c [new file with mode: 0644]
usr/src/usr.bin/talk/get_addrs.c [new file with mode: 0644]
usr/src/usr.bin/talk/get_names.c [new file with mode: 0644]
usr/src/usr.bin/talk/init_disp.c [new file with mode: 0644]
usr/src/usr.bin/talk/invite.c [new file with mode: 0644]
usr/src/usr.bin/talk/io.c [new file with mode: 0644]
usr/src/usr.bin/talk/look_up.c [new file with mode: 0644]
usr/src/usr.bin/talk/msgs.c [new file with mode: 0644]
usr/src/usr.bin/talk/talk.c [new file with mode: 0644]
usr/src/usr.bin/talk/talk.h [new file with mode: 0644]
usr/src/usr.bin/talk/talk_ctl.h [new file with mode: 0644]

diff --git a/usr/src/usr.bin/talk/ctl.c b/usr/src/usr.bin/talk/ctl.c
new file mode 100644 (file)
index 0000000..3b8a1cb
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ctl.c      5.7 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+/*
+ * This file handles haggling with the various talk daemons to
+ * get a socket to talk to. sockt is opened and connected in
+ * the progress
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <protocols/talkd.h>
+#include <netinet/in.h>
+#include "talk.h"
+#include "talk_ctl.h"
+
+struct sockaddr_in daemon_addr = { sizeof(daemon_addr), AF_INET };
+struct sockaddr_in ctl_addr = { sizeof(ctl_addr), AF_INET };
+struct sockaddr_in my_addr = { sizeof(my_addr), AF_INET };
+
+       /* inet addresses of the two machines */
+struct in_addr my_machine_addr;
+struct in_addr his_machine_addr;
+
+u_short daemon_port;   /* port number of the talk daemon */
+
+int    ctl_sockt;
+int    sockt;
+int    invitation_waiting = 0;
+
+CTL_MSG msg;
+
+open_sockt()
+{
+       int length;
+
+       my_addr.sin_addr = my_machine_addr;
+       my_addr.sin_port = 0;
+       sockt = socket(AF_INET, SOCK_STREAM, 0);
+       if (sockt <= 0)
+               p_error("Bad socket");
+       if (bind(sockt, (struct sockaddr *)&my_addr, sizeof(my_addr)) != 0)
+               p_error("Binding local socket");
+       length = sizeof(my_addr);
+       if (getsockname(sockt, (struct sockaddr *)&my_addr, &length) == -1)
+               p_error("Bad address for socket");
+}
+
+/* open the ctl socket */
+open_ctl() 
+{
+       int length;
+
+       ctl_addr.sin_port = 0;
+       ctl_addr.sin_addr = my_machine_addr;
+       ctl_sockt = socket(AF_INET, SOCK_DGRAM, 0);
+       if (ctl_sockt <= 0)
+               p_error("Bad socket");
+       if (bind(ctl_sockt,
+           (struct sockaddr *)&ctl_addr, sizeof(ctl_addr)) != 0)
+               p_error("Couldn't bind to control socket");
+       length = sizeof(ctl_addr);
+       if (getsockname(ctl_sockt,
+           (struct sockaddr *)&ctl_addr, &length) == -1)
+               p_error("Bad address for ctl socket");
+}
+
+/* print_addr is a debug print routine */
+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);
+       for (i = 0; i<8;i++)
+       printf("%o ", (int)addr.sin_zero[i]);
+       putchar('\n');
+}
diff --git a/usr/src/usr.bin/talk/ctl_transact.c b/usr/src/usr.bin/talk/ctl_transact.c
new file mode 100644 (file)
index 0000000..b5c1975
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ctl_transact.c     5.8 (Berkeley) 3/1/91";
+#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 "talk_ctl.h"
+
+#define CTL_WAIT 2     /* time to wait for a response, in seconds */
+
+/*
+ * SOCKDGRAM is unreliable, so we must repeat messages if we have
+ * not recieved an acknowledgement within a reasonable amount
+ * of time
+ */
+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;
+       struct timeval wait;
+
+       msg.type = type;
+       daemon_addr.sin_addr = target;
+       daemon_addr.sin_port = daemon_port;
+       ctl_mask = 1 << ctl_sockt;
+
+       /*
+        * Keep sending the message until a response of
+        * the proper type is obtained.
+        */
+       do {
+               wait.tv_sec = CTL_WAIT;
+               wait.tv_usec = 0;
+               /* resend message until a response is obtained */
+               do {
+                       cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
+                           (struct sockaddr *)&daemon_addr,
+                           sizeof (daemon_addr));
+                       if (cc != sizeof (msg)) {
+                               if (errno == EINTR)
+                                       continue;
+                               p_error("Error on write to talk daemon");
+                       }
+                       read_mask = ctl_mask;
+                       nready = select(32, &read_mask, 0, 0, &wait);
+                       if (nready < 0) {
+                               if (errno == EINTR)
+                                       continue;
+                               p_error("Error waiting for daemon response");
+                       }
+               } while (nready == 0);
+               /*
+                * Keep reading while there are queued messages 
+                * (this is not necessary, it just saves extra
+                * request/acknowledgements being sent)
+                */
+               do {
+                       cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
+                       if (cc < 0) {
+                               if (errno == EINTR)
+                                       continue;
+                               p_error("Error on read from talk daemon");
+                       }
+                       read_mask = ctl_mask;
+                       /* an immediate poll */
+                       timerclear(&wait);
+                       nready = select(32, &read_mask, 0, 0, &wait);
+               } while (nready > 0 && (rp->vers != TALK_VERSION ||
+                   rp->type != type));
+       } while (rp->vers != TALK_VERSION || rp->type != type);
+       rp->id_num = ntohl(rp->id_num);
+       rp->addr.sa_family = ntohs(rp->addr.sa_family);
+}
diff --git a/usr/src/usr.bin/talk/display.c b/usr/src/usr.bin/talk/display.c
new file mode 100644 (file)
index 0000000..8f82ca3
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)display.c  5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * The window 'manager', initializes curses and handles the actual
+ * displaying of text
+ */
+#include "talk.h"
+
+xwin_t my_win;
+xwin_t his_win;
+WINDOW *line_win;
+
+int    curses_initialized = 0;
+
+/*
+ * max HAS to be a function, it is called with
+ * a argument of the form --foo at least once.
+ */
+max(a,b)
+       int a, b;
+{
+
+       return (a > b ? a : b);
+}
+
+/*
+ * Display some text on somebody's window, processing some control
+ * characters while we are at it.
+ */
+display(win, text, size)
+       register xwin_t *win;
+       register char *text;
+       int size;
+{
+       register int i;
+       char cch;
+
+       for (i = 0; i < size; i++) {
+               if (*text == '\n') {
+                       xscroll(win, 0);
+                       text++;
+                       continue;
+               }
+               /* erase character */
+               if (*text == win->cerase) {
+                       wmove(win->x_win, win->x_line, max(--win->x_col, 0));
+                       getyx(win->x_win, win->x_line, win->x_col);
+                       waddch(win->x_win, ' ');
+                       wmove(win->x_win, win->x_line, win->x_col);
+                       getyx(win->x_win, win->x_line, win->x_col);
+                       text++;
+                       continue;
+               }
+               /*
+                * On word erase search backwards until we find
+                * the beginning of a word or the beginning of
+                * the line.
+                */
+               if (*text == win->werase) {
+                       int endcol, xcol, i, c;
+
+                       endcol = win->x_col;
+                       xcol = endcol - 1;
+                       while (xcol >= 0) {
+                               c = readwin(win->x_win, win->x_line, xcol);
+                               if (c != ' ')
+                                       break;
+                               xcol--;
+                       }
+                       while (xcol >= 0) {
+                               c = readwin(win->x_win, win->x_line, xcol);
+                               if (c == ' ')
+                                       break;
+                               xcol--;
+                       }
+                       wmove(win->x_win, win->x_line, xcol + 1);
+                       for (i = xcol + 1; i < endcol; i++)
+                               waddch(win->x_win, ' ');
+                       wmove(win->x_win, win->x_line, xcol + 1);
+                       getyx(win->x_win, win->x_line, win->x_col);
+                       continue;
+               }
+               /* line kill */
+               if (*text == win->kill) {
+                       wmove(win->x_win, win->x_line, 0);
+                       wclrtoeol(win->x_win);
+                       getyx(win->x_win, win->x_line, win->x_col);
+                       text++;
+                       continue;
+               }
+               if (*text == '\f') {
+                       if (win == &my_win)
+                               wrefresh(curscr);
+                       text++;
+                       continue;
+               }
+               if (win->x_col == COLS-1) {
+                       /* check for wraparound */
+                       xscroll(win, 0);
+               }
+               if (*text < ' ' && *text != '\t') {
+                       waddch(win->x_win, '^');
+                       getyx(win->x_win, win->x_line, win->x_col);
+                       if (win->x_col == COLS-1) /* check for wraparound */
+                               xscroll(win, 0);
+                       cch = (*text & 63) + 64;
+                       waddch(win->x_win, cch);
+               } else
+                       waddch(win->x_win, *text);
+               getyx(win->x_win, win->x_line, win->x_col);
+               text++;
+       }
+       wrefresh(win->x_win);
+}
+
+/*
+ * Read the character at the indicated position in win
+ */
+readwin(win, line, col)
+       WINDOW *win;
+{
+       int oldline, oldcol;
+       register int c;
+
+       getyx(win, oldline, oldcol);
+       wmove(win, line, col);
+       c = winch(win);
+       wmove(win, oldline, oldcol);
+       return (c);
+}
+
+/*
+ * Scroll a window, blanking out the line following the current line
+ * so that the current position is obvious
+ */
+xscroll(win, flag)
+       register xwin_t *win;
+       int flag;
+{
+
+       if (flag == -1) {
+               wmove(win->x_win, 0, 0);
+               win->x_line = 0;
+               win->x_col = 0;
+               return;
+       }
+       win->x_line = (win->x_line + 1) % win->x_nlines;
+       win->x_col = 0;
+       wmove(win->x_win, win->x_line, win->x_col);
+       wclrtoeol(win->x_win);
+       wmove(win->x_win, (win->x_line + 1) % win->x_nlines, win->x_col);
+       wclrtoeol(win->x_win);
+       wmove(win->x_win, win->x_line, win->x_col);
+}
diff --git a/usr/src/usr.bin/talk/get_addrs.c b/usr/src/usr.bin/talk/get_addrs.c
new file mode 100644 (file)
index 0000000..ed2ae02
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)get_addrs.c        5.7 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <netdb.h>
+#include <stdio.h>
+#include "talk_ctl.h"
+
+get_addrs(my_machine_name, his_machine_name)
+       char *my_machine_name, *his_machine_name;
+{
+       struct hostent *hp;
+       struct servent *sp;
+
+       msg.pid = htonl(getpid());
+       /* look up the address of the local host */
+       hp = gethostbyname(my_machine_name);
+       if (hp == NULL) {
+               fprintf(stderr, "talk: %s: ", my_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;
+       /* find the server's port */
+       sp = getservbyname("ntalk", "udp");
+       if (sp == 0) {
+               fprintf(stderr, "talk: %s/%s: service is not registered.\n",
+                    "ntalk", "udp");
+               exit(-1);
+       }
+       daemon_port = sp->s_port;
+}
diff --git a/usr/src/usr.bin/talk/get_names.c b/usr/src/usr.bin/talk/get_names.c
new file mode 100644 (file)
index 0000000..0af26b1
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)get_names.c        5.9 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+#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
+ */
+get_names(argc, argv)
+       int argc;
+       char *argv[];
+{
+       char hostname[MAXHOSTNAMELEN];
+       char *his_name, *my_name;
+       char *my_machine_name, *his_machine_name;
+       char *my_tty, *his_tty;
+       register char *cp;
+
+       if (argc < 2 ) {
+               printf("Usage: talk user [ttyname]\n");
+               exit(-1);
+       }
+       if (!isatty(0)) {
+               printf("Standard input must be a tty, not a pipe or a file\n");
+               exit(-1);
+       }
+       if ((my_name = getlogin()) == NULL) {
+               struct passwd *pw;
+
+               if ((pw = getpwuid(getuid())) == NULL) {
+                       printf("You don't exist. Go away.\n");
+                       exit(-1);
+               }
+               my_name = pw->pw_name;
+       }
+       gethostname(hostname, sizeof (hostname));
+       my_machine_name = hostname;
+       /* check for, and strip out, the machine name of the target */
+       for (cp = argv[1]; *cp && !index("@:!.", *cp); cp++)
+               ;
+       if (*cp == '\0') {
+               /* this is a local to local talk */
+               his_name = argv[1];
+               his_machine_name = my_machine_name;
+       } else {
+               if (*cp++ == '@') {
+                       /* user@host */
+                       his_name = argv[1];
+                       his_machine_name = cp;
+               } else {
+                       /* host.user or host!user or host:user */
+                       his_name = cp;
+                       his_machine_name = argv[1];
+               }
+               *--cp = '\0';
+       }
+       if (argc > 2)
+               his_tty = argv[2];      /* tty name is arg 2 */
+       else
+               his_tty = "";
+       get_addrs(my_machine_name, his_machine_name);
+       /*
+        * Initialize the message template.
+        */
+       msg.vers = TALK_VERSION;
+       msg.addr.sa_family = htons(AF_INET);
+       msg.ctl_addr.sa_family = htons(AF_INET);
+       msg.id_num = htonl(0);
+       strncpy(msg.l_name, my_name, NAME_SIZE);
+       msg.l_name[NAME_SIZE - 1] = '\0';
+       strncpy(msg.r_name, his_name, NAME_SIZE);
+       msg.r_name[NAME_SIZE - 1] = '\0';
+       strncpy(msg.r_tty, his_tty, TTY_SIZE);
+       msg.r_tty[TTY_SIZE - 1] = '\0';
+}
diff --git a/usr/src/usr.bin/talk/init_disp.c b/usr/src/usr.bin/talk/init_disp.c
new file mode 100644 (file)
index 0000000..761deac
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init_disp.c        5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * Initialization code for the display package,
+ * as well as the signal handling routines.
+ */
+
+#include "talk.h"
+#include <signal.h>
+
+/* 
+ * Set up curses, catch the appropriate signals,
+ * and build the various windows.
+ */
+init_display()
+{
+       void sig_sent();
+       struct sigvec sigv;
+
+       initscr();
+       (void) sigvec(SIGTSTP, (struct sigvec *)0, &sigv);
+       sigv.sv_mask |= sigmask(SIGALRM);
+       (void) sigvec(SIGTSTP, &sigv, (struct sigvec *)0);
+       curses_initialized = 1;
+       clear();
+       refresh();
+       noecho();
+       crmode();
+       signal(SIGINT, sig_sent);
+       signal(SIGPIPE, sig_sent);
+       /* curses takes care of ^Z */
+       my_win.x_nlines = LINES / 2;
+       my_win.x_ncols = COLS;
+       my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
+       scrollok(my_win.x_win, FALSE);
+       wclear(my_win.x_win);
+
+       his_win.x_nlines = LINES / 2 - 1;
+       his_win.x_ncols = COLS;
+       his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
+           my_win.x_nlines+1, 0);
+       scrollok(his_win.x_win, FALSE);
+       wclear(his_win.x_win);
+
+       line_win = newwin(1, COLS, my_win.x_nlines, 0);
+       box(line_win, '-', '-');
+       wrefresh(line_win);
+       /* let them know we are working on it */
+       current_state = "No connection yet";
+}
+
+/*
+ * Trade edit characters with the other talk. By agreement
+ * the first three characters each talk transmits after
+ * connection are the three edit characters.
+ */
+set_edit_chars()
+{
+       char buf[3];
+       int cc;
+       struct sgttyb tty;
+       struct ltchars ltc;
+       
+       ioctl(0, TIOCGETP, &tty);
+       ioctl(0, TIOCGLTC, (struct sgttyb *)&ltc);
+       my_win.cerase = tty.sg_erase;
+       my_win.kill = tty.sg_kill;
+       if (ltc.t_werasc == (char) -1)
+               my_win.werase = '\027';  /* control W */
+       else
+               my_win.werase = ltc.t_werasc;
+       buf[0] = my_win.cerase;
+       buf[1] = my_win.kill;
+       buf[2] = my_win.werase;
+       cc = write(sockt, buf, sizeof(buf));
+       if (cc != sizeof(buf) )
+               p_error("Lost the connection");
+       cc = read(sockt, buf, sizeof(buf));
+       if (cc != sizeof(buf) )
+               p_error("Lost the connection");
+       his_win.cerase = buf[0];
+       his_win.kill = buf[1];
+       his_win.werase = buf[2];
+}
+
+void
+sig_sent()
+{
+
+       message("Connection closing. Exiting");
+       quit();
+}
+
+/*
+ * All done talking...hang up the phone and reset terminal thingy's
+ */
+quit()
+{
+
+       if (curses_initialized) {
+               wmove(his_win.x_win, his_win.x_nlines-1, 0);
+               wclrtoeol(his_win.x_win);
+               wrefresh(his_win.x_win);
+               endwin();
+       }
+       if (invitation_waiting)
+               send_delete();
+       exit(0);
+}
diff --git a/usr/src/usr.bin/talk/invite.c b/usr/src/usr.bin/talk/invite.c
new file mode 100644 (file)
index 0000000..3042d30
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)invite.c   5.8 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <errno.h>
+#include <setjmp.h>
+#include "talk_ctl.h"
+#include "talk.h"
+
+/*
+ * There wasn't an invitation waiting, so send a request containing
+ * our sockt address to the remote talk daemon so it can invite
+ * him 
+ */
+
+/*
+ * The msg.id's for the invitations
+ * on the local and remote machines.
+ * These are used to delete the 
+ * invitations.
+ */
+int    local_id, remote_id;
+void   re_invite();
+jmp_buf invitebuf;
+
+invite_remote()
+{
+       int nfd, read_mask, template, new_sockt;
+       struct itimerval itimer;
+       CTL_RESPONSE response;
+
+       itimer.it_value.tv_sec = RING_WAIT;
+       itimer.it_value.tv_usec = 0;
+       itimer.it_interval = itimer.it_value;
+       if (listen(sockt, 5) != 0)
+               p_error("Error on attempt to listen for caller");
+#ifdef MSG_EOR
+       /* copy new style sockaddr to old, swap family (short in old) */
+       msg.addr = *(struct osockaddr *)&my_addr;  /* XXX new to old  style*/
+       msg.addr.sa_family = htons(my_addr.sin_family);
+#else
+       msg.addr = *(struct sockaddr *)&my_addr;
+#endif
+       msg.id_num = htonl(-1);         /* an impossible id_num */
+       invitation_waiting = 1;
+       announce_invite();
+       /*
+        * Shut off the automatic messages for a while,
+        * so we can use the interupt timer to resend the invitation
+        */
+       end_msgs();
+       setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+       message("Waiting for your party to respond");
+       signal(SIGALRM, re_invite);
+       (void) setjmp(invitebuf);
+       while ((new_sockt = accept(sockt, 0, 0)) < 0) {
+               if (errno == EINTR)
+                       continue;
+               p_error("Unable to connect with your party");
+       }
+       close(sockt);
+       sockt = new_sockt;
+
+       /*
+        * Have the daemons delete the invitations now that we
+        * have connected.
+        */
+       current_state = "Waiting for your party to respond";
+       start_msgs();
+
+       msg.id_num = htonl(local_id);
+       ctl_transact(my_machine_addr, msg, DELETE, &response);
+       msg.id_num = htonl(remote_id);
+       ctl_transact(his_machine_addr, msg, DELETE, &response);
+       invitation_waiting = 0;
+}
+
+/*
+ * Routine called on interupt to re-invite the callee
+ */
+void
+re_invite()
+{
+
+       message("Ringing your party again");
+       current_line++;
+       /* force a re-announce */
+       msg.id_num = htonl(remote_id + 1);
+       announce_invite();
+       longjmp(invitebuf, 1);
+}
+
+static char *answers[] = {
+       "answer #0",                                    /* SUCCESS */
+       "Your party is not logged on",                  /* NOT_HERE */
+       "Target machine is too confused to talk to us", /* FAILED */
+       "Target machine does not recognize us",         /* MACHINE_UNKNOWN */
+       "Your party is refusing messages",              /* PERMISSION_REFUSED */
+       "Target machine can not handle remote talk",    /* UNKNOWN_REQUEST */
+       "Target machine indicates protocol mismatch",   /* BADVERSION */
+       "Target machine indicates protocol botch (addr)",/* BADADDR */
+       "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */
+};
+#define        NANSWERS        (sizeof (answers) / sizeof (answers[0]))
+
+/*
+ * Transmit the invitation and process the response
+ */
+announce_invite()
+{
+       CTL_RESPONSE response;
+
+       current_state = "Trying to connect to your party's talk daemon";
+       ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
+       remote_id = response.id_num;
+       if (response.answer != SUCCESS) {
+               if (response.answer < NANSWERS)
+                       message(answers[response.answer]);
+               quit();
+       }
+       /* leave the actual invitation on my talk daemon */
+       ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
+       local_id = response.id_num;
+}
+
+/*
+ * Tell the daemon to remove your invitation
+ */
+send_delete()
+{
+
+       msg.type = DELETE;
+       /*
+        * This is just a extra clean up, so just send it
+        * and don't wait for an answer
+        */
+       msg.id_num = htonl(remote_id);
+       daemon_addr.sin_addr = his_machine_addr;
+       if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
+           (struct sockaddr *)&daemon_addr,
+           sizeof (daemon_addr)) != sizeof(msg))
+               perror("send_delete (remote)");
+       msg.id_num = htonl(local_id);
+       daemon_addr.sin_addr = my_machine_addr;
+       if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
+           (struct sockaddr *)&daemon_addr,
+           sizeof (daemon_addr)) != sizeof (msg))
+               perror("send_delete (local)");
+}
diff --git a/usr/src/usr.bin/talk/io.c b/usr/src/usr.bin/talk/io.c
new file mode 100644 (file)
index 0000000..4b77ac4
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)io.c       5.6 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+/*
+ * This file contains the I/O handling and the exchange of 
+ * edit characters. This connection itself is established in
+ * ctl.c
+ */
+
+#include <sys/time.h>
+#include "talk.h"
+#include <stdio.h>
+#include <errno.h>
+#include <string.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
+ */
+talk()
+{
+       register int read_template, sockt_mask;
+       int read_set, nb;
+       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;
+       for (;;) {
+               read_set = read_template;
+               wait.tv_sec = A_LONG_TIME;
+               wait.tv_usec = 0;
+               nb = select(32, &read_set, 0, 0, &wait);
+               if (nb <= 0) {
+                       if (errno == EINTR) {
+                               read_set = read_template;
+                               continue;
+                       }
+                       /* panic, we don't know what happened */
+                       p_error("Unexpected error from select");
+                       quit();
+               }
+               if (read_set & sockt_mask) { 
+                       /* There is data on sockt */
+                       nb = read(sockt, buf, sizeof buf);
+                       if (nb <= 0) {
+                               message("Connection closed. Exiting");
+                               quit();
+                       }
+                       display(&his_win, buf, nb);
+               }
+               if (read_set & STDIN_MASK) {
+                       /*
+                        * We can't make the tty non_blocking, because
+                        * curses's output routines would screw up
+                        */
+                       ioctl(0, FIONREAD, (struct sgttyb *) &nb);
+                       nb = read(0, buf, nb);
+                       display(&my_win, buf, nb);
+                       /* might lose data here because sockt is non-blocking */
+                       write(sockt, buf, nb);
+               }
+       }
+}
+
+extern int errno;
+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)
+ */
+p_error(string) 
+       char *string;
+{
+       wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
+       wprintw(my_win.x_win, "[%s : %s (%d)]\n",
+           string, strerror(errno), errno);
+       wrefresh(my_win.x_win);
+       move(LINES-1, 0);
+       refresh();
+       quit();
+}
+
+/*
+ * Display string in the standard location
+ */
+message(string)
+       char *string;
+{
+
+       wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
+       wprintw(my_win.x_win, "[%s]\n", string);
+       wrefresh(my_win.x_win);
+}
diff --git a/usr/src/usr.bin/talk/look_up.c b/usr/src/usr.bin/talk/look_up.c
new file mode 100644 (file)
index 0000000..4913856
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)look_up.c  5.7 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <protocols/talkd.h>
+#include <errno.h>
+#include "talk_ctl.h"
+#include "talk.h"
+
+/*
+ * See if the local daemon has an invitation for us.
+ */
+check_local()
+{
+       CTL_RESPONSE response;
+       register CTL_RESPONSE *rp = &response;
+
+       /* the rest of msg was set up in get_names */
+#ifdef MSG_EOR
+       /* copy new style sockaddr to old, swap family (short in old) */
+       msg.ctl_addr = *(struct osockaddr *)&ctl_addr;
+       msg.ctl_addr.sa_family = htons(ctl_addr.sin_family);
+#else
+       msg.ctl_addr = *(struct sockaddr *)&ctl_addr;
+#endif
+       /* must be initiating a talk */
+       if (!look_for_invite(rp))
+               return (0);
+       /*
+        * There was an invitation waiting for us, 
+        * so connect with the other (hopefully waiting) party 
+        */
+       current_state = "Waiting to connect with caller";
+       do {
+               if (rp->addr.sa_family != AF_INET)
+                       p_error("Response uses invalid network address");
+               errno = 0;
+               if (connect(sockt,
+                   (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1)
+                       return (1);
+       } while (errno == EINTR);
+       if (errno == ECONNREFUSED) {
+               /*
+                * The caller gave up, but his invitation somehow
+                * was not cleared. Clear it and initiate an 
+                * invitation. (We know there are no newer invitations,
+                * the talkd works LIFO.)
+                */
+               ctl_transact(his_machine_addr, msg, DELETE, rp);
+               close(sockt);
+               open_sockt();
+               return (0);
+       }
+       p_error("Unable to connect with initiator");
+       /*NOTREACHED*/
+}
+
+/*
+ * Look for an invitation on 'machine'
+ */
+look_for_invite(rp)
+       CTL_RESPONSE *rp;
+{
+       struct in_addr machine_addr;
+
+       current_state = "Checking for invitation on caller's machine";
+       ctl_transact(his_machine_addr, msg, LOOK_UP, rp);
+       /* the switch is for later options, such as multiple invitations */
+       switch (rp->answer) {
+
+       case SUCCESS:
+               msg.id_num = htonl(rp->id_num);
+               return (1);
+
+       default:
+               /* there wasn't an invitation waiting for us */
+               return (0);
+       }
+}
diff --git a/usr/src/usr.bin/talk/msgs.c b/usr/src/usr.bin/talk/msgs.c
new file mode 100644 (file)
index 0000000..063c6b5
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)msgs.c     5.6 (Berkeley) 3/1/91";
+#endif /* not lint */
+
+/* 
+ * A package to display what is happening every MSG_INTERVAL seconds
+ * if we are slow connecting.
+ */
+
+#include <sys/time.h>
+#include <signal.h>
+#include <stdio.h>
+#include "talk.h"
+
+#define MSG_INTERVAL 4
+
+char   *current_state;
+int    current_line = 0;
+
+void
+disp_msg()
+{
+       message(current_state);
+}
+
+start_msgs()
+{
+       struct itimerval itimer;
+
+       message(current_state);
+       signal(SIGALRM, disp_msg);
+       itimer.it_value.tv_sec = itimer.it_interval.tv_sec = MSG_INTERVAL;
+       itimer.it_value.tv_usec = itimer.it_interval.tv_usec = 0;
+       setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+}
+
+end_msgs()
+{
+       struct itimerval itimer;
+
+       timerclear(&itimer.it_value);
+       timerclear(&itimer.it_interval);
+       setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+       signal(SIGALRM, SIG_DFL);
+}
diff --git a/usr/src/usr.bin/talk/talk.c b/usr/src/usr.bin/talk/talk.c
new file mode 100644 (file)
index 0000000..ef1f3c8
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)talk.c     5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "talk.h"
+
+/*
+ * talk:       A visual form of write. Using sockets, a two way 
+ *             connection is set up between the two people talking. 
+ *             With the aid of curses, the screen is split into two 
+ *             windows, and each users text is added to the window,
+ *             one character at a time...
+ *
+ *             Written by Kipp Hickman
+ *             
+ *             Modified to run under 4.1a by Clem Cole and Peter Moore
+ *             Modified to run between hosts by Peter Moore, 8/19/82
+ *             Modified to run under 4.1c by Peter Moore 3/17/83
+ */
+
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       get_names(argc, argv);
+       init_display();
+       open_ctl();
+       open_sockt();
+       start_msgs();
+       if (!check_local())
+               invite_remote();
+       end_msgs();
+       set_edit_chars();
+       talk();
+}
diff --git a/usr/src/usr.bin/talk/talk.h b/usr/src/usr.bin/talk/talk.h
new file mode 100644 (file)
index 0000000..ed2f0b6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *     @(#)talk.h      5.7 (Berkeley) 3/1/91
+ */
+
+#include <curses.h>
+
+extern int sockt;
+extern int curses_initialized;
+extern int invitation_waiting;
+
+extern char *current_state;
+extern int current_line;
+
+typedef struct xwin {
+       WINDOW  *x_win;
+       int     x_nlines;
+       int     x_ncols;
+       int     x_line;
+       int     x_col;
+       char    kill;
+       char    cerase;
+       char    werase;
+} xwin_t;
+
+extern xwin_t my_win;
+extern xwin_t his_win;
+extern WINDOW *line_win;
diff --git a/usr/src/usr.bin/talk/talk_ctl.h b/usr/src/usr.bin/talk/talk_ctl.h
new file mode 100644 (file)
index 0000000..70a89bc
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *     @(#)talk_ctl.h  5.6 (Berkeley) 3/1/91
+ */
+
+extern struct sockaddr_in daemon_addr;
+extern struct sockaddr_in ctl_addr;
+extern struct sockaddr_in my_addr;
+extern struct in_addr my_machine_addr;
+extern struct in_addr his_machine_addr;
+extern u_short daemon_port;
+extern int ctl_sockt;
+extern CTL_MSG msg;