home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / bridge / part01 / invite.c < prev    next >
C/C++ Source or Header  |  1988-05-31  |  4KB  |  159 lines

  1. #ifndef lint
  2. static    char sccsid[] = "@(#)invite.c 1.1 86/02/05 SMI"; /* from UCB 1.7 83/07/06 */
  3. #endif
  4.  
  5. #include "talk_ctl.h"
  6. #include <sys/time.h>
  7. #include <signal.h>
  8. #include <setjmp.h>
  9.     
  10.     /*
  11.      * there wasn't an invitation waiting, so send a request containing
  12.      * our sockt address to the remote talk daemon so it can invite
  13.      * him 
  14.      */
  15.  
  16. int local_id, remote_id;    /* the msg.id's for the invitations
  17.                    on the local and remote machines.
  18.                    These are used to delete the 
  19.                    invitations. */
  20. void re_invite();
  21. jmp_buf    invitebuf;
  22.  
  23. invite_remote()
  24. {
  25.     int nfd, read_mask, template, new_sockt;
  26.     struct itimerval itimer;
  27.     CTL_RESPONSE response;
  28.  
  29.     itimer.it_value.tv_sec = RING_WAIT;
  30.     itimer.it_value.tv_usec = 0;
  31.     itimer.it_interval = itimer.it_value;
  32.  
  33.     if (listen(sockt, 5) != 0) {
  34.     p_error("Error on attempt to listen for caller");
  35.     }
  36.  
  37.     msg.addr = my_addr;
  38.     msg.id_num = -1;        /* an impossible id_num */
  39.  
  40.     invitation_waiting = 1;
  41.  
  42.     announce_invite();
  43.  
  44.     /*
  45.      * shut off the automatic messages for a while,
  46.      * so we can use the interupt timer to resend the invitation
  47.      */
  48.  
  49.     setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
  50.     message("Waiting for your party to respond");
  51.     signal(SIGALRM, re_invite);
  52.     (void) setjmp(invitebuf);
  53.  
  54.     while ((new_sockt = accept(sockt, 0, 0)) < 0) {
  55.     if (errno != EINTR) {
  56.         p_error("Unable to connect with your party");
  57.     } else {
  58.         /* we just returned from a interupt, keep trying */
  59.         continue;
  60.     }
  61.     }
  62.  
  63.     close(sockt);
  64.     sockt = new_sockt;
  65.  
  66.     /* have the daemons delete the invitations now that we
  67.        have connected.
  68.      */
  69.  
  70.     current_state = "Waiting for your party to respond";
  71.  
  72.     msg.id_num = local_id;
  73.     ctl_transact(my_machine_addr, msg, DELETE, &response);
  74.     msg.id_num = remote_id;
  75.     ctl_transact(his_machine_addr, msg, DELETE, &response);
  76.     invitation_waiting = 0;
  77. }
  78.  
  79.     /* routine called on interupt to re-invite the callee */
  80.  
  81. void re_invite()
  82. {
  83.     message("Ringing your party again");
  84.     current_line++;
  85.     /* force a re-announce */
  86.     msg.id_num = remote_id + 1;
  87.     announce_invite();
  88.     longjmp(invitebuf, 1);
  89. }
  90.  
  91.     /* transmit the invitation and process the response */
  92.  
  93. announce_invite()
  94. {
  95.     CTL_RESPONSE response;
  96.  
  97.     current_state = "Trying to connect to your party's talk daemon";
  98.  
  99.     ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
  100.     remote_id = response.id_num;
  101.  
  102.     if (response.answer != SUCCESS) {
  103.  
  104.     switch (response.answer) {
  105.         
  106.         case NOT_HERE :
  107.         message("Your party is not logged on");
  108.         break;
  109.  
  110.         case MACHINE_UNKNOWN :
  111.         message("Target machine does not recognize us");
  112.         break;
  113.  
  114.         case UNKNOWN_REQUEST :
  115.         message("Target machine can not handle remote talk");
  116.         break;
  117.  
  118.         case FAILED :
  119.         message("Target machine is too confused to talk to us");
  120.         break;
  121.  
  122.         case PERMISSION_DENIED :
  123.         message("Your party is refusing messages");
  124.         break;
  125.     }
  126.  
  127.     quit();
  128.     }
  129.  
  130.     /* leave the actual invitation on my talk daemon */
  131.  
  132.     ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
  133.     local_id = response.id_num;
  134. }
  135.     
  136. send_delete()
  137. {
  138.     /* tell the daemon to remove your invitation */
  139.  
  140.     msg.type = DELETE;
  141.  
  142.     /* this is just a extra clean up, so just send it
  143.        and don't wait for an answer */
  144.  
  145.     msg.id_num = remote_id;
  146.     daemon_addr.sin_addr = his_machine_addr;
  147.     if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr,
  148.             sizeof(daemon_addr)) != sizeof(CTL_MSG)) {
  149.         perror("send_delete remote");
  150.     }
  151.  
  152.     msg.id_num = local_id;
  153.     daemon_addr.sin_addr = my_machine_addr;
  154.     if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr,
  155.             sizeof(daemon_addr)) != sizeof(CTL_MSG)) {
  156.         perror("send_delete local");
  157.     }
  158. }
  159.