Exemplo n.º 1
0
int
invite_remote (void)
{
  int 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");

  msg.addr.sa_family = htons (my_addr.sin_family);
  memcpy (msg.addr.sa_data,
	  ((struct sockaddr *) &my_addr)->sa_data,
	  sizeof ((struct sockaddr *) & my_addr)->sa_data);

  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);
  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;

  return 0;
}
Exemplo n.º 2
0
/*
 * Transmit the invitation and process the response
 */
void
announce_invite(void)
{
	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)
		quit(response.answer < NANSWERS ? answers[response.answer] : NULL, 0);
	/* leave the actual invitation on my talk daemon */
	ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
	local_id = response.id_num;
}
Exemplo n.º 3
0
/*
 * 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*/
}
Exemplo n.º 4
0
/** Look for an invitation on remote machine */
int TalkConnection::look_for_invite(int mandatory)
{
    /* Check for invitation on caller's machine */
    ctl_transact(LOOK_UP, 0);

    uint8_t answer;
    uint32_t id_num;
    getResponseItems(&answer, &id_num, &lookup_addr);

    if (!mandatory) return 0;

    /* the switch is for later options, such as multiple invitations */
    switch (answer) {

	case SUCCESS:
            new_msg.id_num = htonl(id_num);
            old_msg.id_num = htonl(id_num);
            ktalk_debug("TalkConnection::look_for_invite : got SUCCESS");
            if (lookup_addr.ta_family != AF_INET)
                p_error("Response uses invalid network address");
            return (1);

	default:
            /* there wasn't an invitation waiting for us */
            ktalk_debug("TalkConnection::look_for_invite : didn't get SUCCESS");
            return (0);
    }
}
Exemplo n.º 5
0
int
check_local()
{
	CTL_RESPONSE response;

	/* the rest of msg was set up in get_names */

	msg.ctl_addr = ctl_addr;

	if (!look_for_invite(&response)) {

		/* we must be initiating a talk */

		return (0);
	}

	/*
	 * there was an invitation waiting for us,
	 * so connect with the other (hopefully waiting) party
	 */

	current_state = gettext("Waiting to connect with caller");

	response = swapresponse(response);
	while (connect(sockt, (struct sockaddr *)&response.addr,
		sizeof (response.addr)) != 0) {
		if (errno == ECONNREFUSED) {

			/*
			 * the caller gave up, but the invitation somehow
			 * was not cleared. Clear it and initiate an
			 * invitation. (We know there are no newer invitations,
			 * the talkd works LIFO.)
			 */

			ctl_transact(rem_machine_addr, msg, DELETE, &response);
			close(sockt);
			open_sockt();
			return (0);
		} else if (errno == EINTR) {

		/* we have returned from an interupt handler */
			continue;
		} else {
			p_error(gettext("Unable to connect with initiator"));
		}
	}

	return (1);
}
Exemplo n.º 6
0
/*
 * See if the local daemon has an invitation for us.
 */
int
check_local(void)
{
	CTL_RESPONSE response;
	CTL_RESPONSE *rp = &response;
	struct sockaddr addr;

	/* 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");
		(void)memcpy(&addr, &rp->addr.sa_family, sizeof(addr));
		addr.sa_family = rp->addr.sa_family;
		addr.sa_len = sizeof(addr);
		errno = 0;
		if (connect(sockt, &addr, sizeof(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*/
	return (0);
}
Exemplo n.º 7
0
/*
 * Look for an invitation on 'machine'
 */
int
look_for_invite(CTL_RESPONSE *rp)
{
	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);
	}
}
Exemplo n.º 8
0
/*
 * See if the local daemon has an invitation for us.
 */
int
check_local()
{
	CTL_RESPONSE response;
	register CTL_RESPONSE *rp = &response;

	/* the rest of msg was set up in get_names */
	msg.ctl_addr.sa_family = htons (ctl_addr.sin_family);
	memcpy (msg.ctl_addr.sa_data,
		((struct sockaddr *)&ctl_addr)->sa_data,
		sizeof ((struct sockaddr *)&ctl_addr)->sa_data);

	/* 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*/
}
Exemplo n.º 9
0
/** Connect to another talk client. */
int TalkConnection::connect()
{
    ktalk_debug("Waiting to connect");
    do {
        errno = 0;
        if (::connect(sockt, (const sockaddr *)(&lookup_addr), sizeof (struct talk_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.)
         */
        ktalk_debug("ECONNREFUSED");
        ctl_transact(DELETE, 0);
        close_sockets();
        return 0;
    }
    p_error("Unable to connect with initiator");
    /*NOTREACHED*/
    return 0;
}
Exemplo n.º 10
0
void
invite_remote(void)
{
	int new_sockt;
	struct itimerval itimer;
	CTL_RESPONSE response;
	struct sockaddr rp;
	socklen_t rplen = sizeof(struct sockaddr);
	struct hostent *rphost;
	char rname[STRING_LENGTH];

	itimer.it_value.tv_sec = RING_WAIT;
	itimer.it_value.tv_usec = 0;
	itimer.it_interval = itimer.it_value;
	if (listen(sockt, 5) != 0)
		quit("Error on attempt to listen for caller", 1);
#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 interrupt timer to resend the invitation.
	 * We no longer turn automatic messages back on to avoid a bonus
	 * message after we've connected; this is okay even though end_msgs()
	 * gets called again in main().
	 */
	end_msgs();
	setitimer(ITIMER_REAL, &itimer, NULL);
	message("Waiting for your party to respond");
	signal(SIGALRM, re_invite);
	(void) setjmp(invitebuf);
	while ((new_sockt = accept(sockt, &rp, &rplen)) == -1) {
		if (errno == EINTR || errno == EWOULDBLOCK ||
		    errno == ECONNABORTED)
			continue;
		quit("Unable to connect with your party", 1);
	}
	close(sockt);
	sockt = new_sockt;

	/*
	 * Have the daemons delete the invitations now that we
	 * have connected.
	 */
	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;

	/*
	 * Check to see if the other guy is coming from the machine
	 * we expect.
	 */
	if (his_machine_addr.s_addr !=
	    ((struct sockaddr_in *)&rp)->sin_addr.s_addr) {
		rphost = gethostbyaddr((char *) &((struct sockaddr_in
		    *)&rp)->sin_addr, sizeof(struct in_addr), AF_INET);
		if (rphost)
			snprintf(rname, STRING_LENGTH,
			    "Answering talk request from %s@%s", msg.r_name,
			    rphost->h_name);
		else
			snprintf(rname, STRING_LENGTH,
			    "Answering talk request from %s@%s", msg.r_name,
			    inet_ntoa(((struct sockaddr_in *)&rp)->sin_addr));
		message(rname);
	}
}