home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / inetutils-1.2-src.tgz / tar.out / fsf / inetutils / talk / invite.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  195 lines

  1. /*
  2.  * Copyright (c) 1983, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)invite.c    8.1 (Berkeley) 6/6/93";
  36. #endif /* not lint */
  37.  
  38. #ifdef HAVE_CONFIG_H
  39. #include <config.h>
  40. #endif
  41.  
  42. #include <sys/types.h>
  43. #include <sys/socket.h>
  44. #include <sys/time.h>
  45. #include <signal.h>
  46. #include <netinet/in.h>
  47. #ifdef HAVE_OSOCKADDR_H
  48. #include <osockaddr.h>
  49. #endif
  50. #include <protocols/talkd.h>
  51. #include <errno.h>
  52. #include <setjmp.h>
  53. #include "talk_ctl.h"
  54. #include "talk.h"
  55.  
  56. /*
  57.  * There wasn't an invitation waiting, so send a request containing
  58.  * our sockt address to the remote talk daemon so it can invite
  59.  * him 
  60.  */
  61.  
  62. /*
  63.  * The msg.id's for the invitations
  64.  * on the local and remote machines.
  65.  * These are used to delete the 
  66.  * invitations.
  67.  */
  68. int    local_id, remote_id;
  69. void    re_invite();
  70. jmp_buf invitebuf;
  71.  
  72. invite_remote()
  73. {
  74.     int nfd, read_mask, template, new_sockt;
  75.     struct itimerval itimer;
  76.     CTL_RESPONSE response;
  77.  
  78.     itimer.it_value.tv_sec = RING_WAIT;
  79.     itimer.it_value.tv_usec = 0;
  80.     itimer.it_interval = itimer.it_value;
  81.     if (listen(sockt, 5) != 0)
  82.         p_error("Error on attempt to listen for caller");
  83.  
  84.     msg.addr.sa_family = htons (my_addr.sin_family);
  85.     bcopy (msg.addr.sa_data,
  86.            ((struct sockaddr *)&my_addr)->sa_data,
  87.            sizeof ((struct sockaddr *)&my_addr)->sa_data);
  88.  
  89.     msg.id_num = htonl(-1);        /* an impossible id_num */
  90.     invitation_waiting = 1;
  91.     announce_invite();
  92.     /*
  93.      * Shut off the automatic messages for a while,
  94.      * so we can use the interupt timer to resend the invitation
  95.      */
  96.     end_msgs();
  97.     setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
  98.     message("Waiting for your party to respond");
  99.     signal(SIGALRM, re_invite);
  100.     (void) setjmp(invitebuf);
  101.     while ((new_sockt = accept(sockt, 0, 0)) < 0) {
  102.         if (errno == EINTR)
  103.             continue;
  104.         p_error("Unable to connect with your party");
  105.     }
  106.     close(sockt);
  107.     sockt = new_sockt;
  108.  
  109.     /*
  110.      * Have the daemons delete the invitations now that we
  111.      * have connected.
  112.      */
  113.     current_state = "Waiting for your party to respond";
  114.     start_msgs();
  115.  
  116.     msg.id_num = htonl(local_id);
  117.     ctl_transact(my_machine_addr, msg, DELETE, &response);
  118.     msg.id_num = htonl(remote_id);
  119.     ctl_transact(his_machine_addr, msg, DELETE, &response);
  120.     invitation_waiting = 0;
  121. }
  122.  
  123. /*
  124.  * Routine called on interupt to re-invite the callee
  125.  */
  126. void
  127. re_invite()
  128. {
  129.  
  130.     message("Ringing your party again");
  131.     current_line++;
  132.     /* force a re-announce */
  133.     msg.id_num = htonl(remote_id + 1);
  134.     announce_invite();
  135.     longjmp(invitebuf, 1);
  136. }
  137.  
  138. static    char *answers[] = {
  139.     "answer #0",                    /* SUCCESS */
  140.     "Your party is not logged on",            /* NOT_HERE */
  141.     "Target machine is too confused to talk to us",    /* FAILED */
  142.     "Target machine does not recognize us",        /* MACHINE_UNKNOWN */
  143.     "Your party is refusing messages",        /* PERMISSION_REFUSED */
  144.     "Target machine can not handle remote talk",    /* UNKNOWN_REQUEST */
  145.     "Target machine indicates protocol mismatch",    /* BADVERSION */
  146.     "Target machine indicates protocol botch (addr)",/* BADADDR */
  147.     "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */
  148. };
  149. #define    NANSWERS    (sizeof (answers) / sizeof (answers[0]))
  150.  
  151. /*
  152.  * Transmit the invitation and process the response
  153.  */
  154. announce_invite()
  155. {
  156.     CTL_RESPONSE response;
  157.  
  158.     current_state = "Trying to connect to your party's talk daemon";
  159.     ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
  160.     remote_id = response.id_num;
  161.     if (response.answer != SUCCESS) {
  162.         if (response.answer < NANSWERS)
  163.             message(answers[response.answer]);
  164.         quit();
  165.     }
  166.     /* leave the actual invitation on my talk daemon */
  167.     ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
  168.     local_id = response.id_num;
  169. }
  170.  
  171. /*
  172.  * Tell the daemon to remove your invitation
  173.  */
  174. send_delete()
  175. {
  176.  
  177.     msg.type = DELETE;
  178.     /*
  179.      * This is just a extra clean up, so just send it
  180.      * and don't wait for an answer
  181.      */
  182.     msg.id_num = htonl(remote_id);
  183.     daemon_addr.sin_addr = his_machine_addr;
  184.     if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
  185.         (struct sockaddr *)&daemon_addr,
  186.         sizeof (daemon_addr)) != sizeof(msg))
  187.         perror("send_delete (remote)");
  188.     msg.id_num = htonl(local_id);
  189.     daemon_addr.sin_addr = my_machine_addr;
  190.     if (sendto(ctl_sockt, &msg, sizeof (msg), 0,
  191.         (struct sockaddr *)&daemon_addr,
  192.         sizeof (daemon_addr)) != sizeof (msg))
  193.         perror("send_delete (local)");
  194. }
  195.