ctl_transact.c revision 178642
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 3487710Smarkm#include <sys/cdefs.h> 3587710Smarkm 3687710Smarkm__FBSDID("$FreeBSD: head/usr.bin/talk/ctl_transact.c 178642 2008-04-28 21:08:42Z delphij $"); 3787710Smarkm 381590Srgrimes#ifndef lint 3987710Smarkmstatic const char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) 6/6/93"; 4032503Scharnier#endif 411590Srgrimes 4290868Smike#include <arpa/inet.h> 4390868Smike 441590Srgrimes#include <errno.h> 4514443Sjoerg#include <string.h> 4687710Smarkm 4714443Sjoerg#include "talk.h" 481590Srgrimes#include "talk_ctl.h" 491590Srgrimes 501590Srgrimes#define CTL_WAIT 2 /* time to wait for a response, in seconds */ 511590Srgrimes 521590Srgrimes/* 531590Srgrimes * SOCKDGRAM is unreliable, so we must repeat messages if we have 541590Srgrimes * not recieved an acknowledgement within a reasonable amount 551590Srgrimes * of time 561590Srgrimes */ 5714443Sjoergvoid 58178642Sdelphijctl_transact(struct in_addr target, CTL_MSG lmsg, int type, CTL_RESPONSE *rp) 591590Srgrimes{ 6014443Sjoerg fd_set read_mask, ctl_mask; 6114443Sjoerg int nready = 0, cc; 621590Srgrimes struct timeval wait; 631590Srgrimes 6487710Smarkm lmsg.type = type; 651590Srgrimes daemon_addr.sin_addr = target; 661590Srgrimes daemon_addr.sin_port = daemon_port; 6714443Sjoerg FD_ZERO(&ctl_mask); 6814443Sjoerg FD_SET(ctl_sockt, &ctl_mask); 691590Srgrimes 701590Srgrimes /* 711590Srgrimes * Keep sending the message until a response of 721590Srgrimes * the proper type is obtained. 731590Srgrimes */ 741590Srgrimes do { 751590Srgrimes wait.tv_sec = CTL_WAIT; 761590Srgrimes wait.tv_usec = 0; 771590Srgrimes /* resend message until a response is obtained */ 781590Srgrimes do { 7987710Smarkm cc = sendto(ctl_sockt, (char *)&lmsg, sizeof (lmsg), 0, 801590Srgrimes (struct sockaddr *)&daemon_addr, 811590Srgrimes sizeof (daemon_addr)); 8287710Smarkm if (cc != sizeof (lmsg)) { 831590Srgrimes if (errno == EINTR) 841590Srgrimes continue; 851590Srgrimes p_error("Error on write to talk daemon"); 861590Srgrimes } 871590Srgrimes read_mask = ctl_mask; 881590Srgrimes nready = select(32, &read_mask, 0, 0, &wait); 891590Srgrimes if (nready < 0) { 901590Srgrimes if (errno == EINTR) 911590Srgrimes continue; 921590Srgrimes p_error("Error waiting for daemon response"); 931590Srgrimes } 941590Srgrimes } while (nready == 0); 951590Srgrimes /* 968874Srgrimes * Keep reading while there are queued messages 971590Srgrimes * (this is not necessary, it just saves extra 981590Srgrimes * request/acknowledgements being sent) 991590Srgrimes */ 1001590Srgrimes do { 1011590Srgrimes cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); 1021590Srgrimes if (cc < 0) { 1031590Srgrimes if (errno == EINTR) 1041590Srgrimes continue; 1051590Srgrimes p_error("Error on read from talk daemon"); 1061590Srgrimes } 1071590Srgrimes read_mask = ctl_mask; 1081590Srgrimes /* an immediate poll */ 1091590Srgrimes timerclear(&wait); 1101590Srgrimes nready = select(32, &read_mask, 0, 0, &wait); 1111590Srgrimes } while (nready > 0 && (rp->vers != TALK_VERSION || 1121590Srgrimes rp->type != type)); 1131590Srgrimes } while (rp->vers != TALK_VERSION || rp->type != type); 1141590Srgrimes rp->id_num = ntohl(rp->id_num); 1151590Srgrimes rp->addr.sa_family = ntohs(rp->addr.sa_family); 1161590Srgrimes} 117