date and time created 86/07/29 09:36:02 by mckusick
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Wed, 30 Jul 1986 00:36:02 +0000 (16:36 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Wed, 30 Jul 1986 00:36:02 +0000 (16:36 -0800)
SCCS-vsn: old/talk/talk/look_up.c 6.1

usr/src/old/talk/talk/look_up.c [new file with mode: 0644]

diff --git a/usr/src/old/talk/talk/look_up.c b/usr/src/old/talk/talk/look_up.c
new file mode 100644 (file)
index 0000000..19409a6
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/* from "@(#)look_up.c 5.1 (Berkeley) 6/6/85"; */
+
+#ifndef lint
+static char sccsid[] = "@(#)look_up.c  6.1 (Berkeley) %G%";
+#endif not lint
+
+#include "talk_ctl.h"
+
+
+/*
+ * See if the local daemon has a invitation for us
+ */
+check_local()
+{
+       CTL_RESPONSE response;
+
+       /* the rest of msg was set up in get_names */
+       msg.ctl_addr = ctl_addr;
+       /* must be initiating a talk */
+       if (!look_for_invite(&response))
+               return (0);
+       /*
+        * There was an invitation waiting for us, 
+        * so connect with the other (hopefully waiting) party 
+        */
+       current_state = "Waiting to connect with caller";
+again:
+       swapresponse(&response);
+       if (connect(sockt, &response.addr, sizeof(response.addr)) != -1)
+               return (1);
+       if (errno == EINTR)
+               goto again;
+       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, &response);
+               close(sockt);
+               open_sockt();
+               return (0);
+       }
+       p_error("Unable to connect with initiator");
+       /*NOTREACHED*/
+}
+
+/*
+ * Look for an invitation on 'machine'
+ */
+look_for_invite(response)
+       CTL_RESPONSE *response;
+{
+       struct in_addr machine_addr;
+
+       current_state = "Checking for invitation on caller's machine";
+       ctl_transact(his_machine_addr, msg, LOOK_UP, response);
+       /* the switch is for later options, such as multiple invitations */
+       switch (response->answer) {
+
+       case SUCCESS:
+               msg.id_num = response->id_num;
+               return (1);
+
+       default :
+               /* there wasn't an invitation waiting for us */
+               return (0);
+       }
+}
+
+/*  
+ * heuristic to detect if need to reshuffle CTL_RESPONSE structure
+ */
+
+#define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
+#define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
+
+#ifdef sun
+struct ctl_response_vax {
+       char type;
+       char answer;
+       short junk;
+       int id_num;
+       struct sockaddr_in addr;
+};
+
+swapresponse(rsp)
+       CTL_RESPONSE *rsp;
+{
+       struct ctl_response_vax swaprsp;
+       
+       if (rsp->addr.sin_family != AF_INET) {
+               bcopy(rsp, &swaprsp, sizeof(CTL_RESPONSE));
+               swaprsp.addr.sin_family = swapshort(swaprsp.addr.sin_family);
+               if (swaprsp.addr.sin_family == AF_INET) {
+                       rsp->addr = swaprsp.addr;
+                       rsp->type = swaprsp.type;
+                       rsp->answer = swaprsp.answer;
+                       rsp->id_num = swaplong(swaprsp.id_num);
+               }
+       }
+}
+#endif
+
+#ifdef vax
+struct ctl_response_sun {
+       char type;
+       char answer;
+       unsigned short id_num2;
+       unsigned short id_num1;
+       short sin_family;
+       short sin_port;
+       short sin_addr2;
+       short sin_addr1;
+};
+
+swapresponse(rsp)
+       CTL_RESPONSE *rsp;
+{
+       struct ctl_response_sun swaprsp;
+       
+       if (rsp->addr.sin_family != AF_INET) {
+               bcopy(rsp, &swaprsp, sizeof(struct ctl_response_sun));
+               if (swaprsp.sin_family == swapshort(AF_INET)) {
+                       rsp->type = swaprsp.type;
+                       rsp->answer = swaprsp.answer;
+                       rsp->id_num = swapshort(swaprsp.id_num1)
+                           | (swapshort(swaprsp.id_num2) << 16);
+                       rsp->addr.sin_family = swapshort(swaprsp.sin_family);
+                       rsp->addr.sin_port = swaprsp.sin_port;
+                       rsp->addr.sin_addr.s_addr =
+                           swaprsp.sin_addr2 | (swaprsp.sin_addr1 << 16);
+               }
+       }
+}
+#endif