1 1.11 joerg /* $NetBSD: ctl_transact.c,v 1.11 2011/09/06 18:32:03 joerg Exp $ */ 2 1.3 jtc 3 1.1 cgd /* 4 1.3 jtc * Copyright (c) 1983, 1993 5 1.3 jtc * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.9 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.4 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.3 jtc #if 0 35 1.3 jtc static char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) 6/6/93"; 36 1.3 jtc #endif 37 1.11 joerg __RCSID("$NetBSD: ctl_transact.c,v 1.11 2011/09/06 18:32:03 joerg Exp $"); 38 1.1 cgd #endif /* not lint */ 39 1.1 cgd 40 1.4 lukem #include "talk.h" 41 1.1 cgd #include <sys/time.h> 42 1.1 cgd #include <errno.h> 43 1.4 lukem #include <unistd.h> 44 1.7 itojun #include <poll.h> 45 1.1 cgd #include "talk_ctl.h" 46 1.1 cgd 47 1.1 cgd #define CTL_WAIT 2 /* time to wait for a response, in seconds */ 48 1.1 cgd 49 1.1 cgd /* 50 1.1 cgd * SOCKDGRAM is unreliable, so we must repeat messages if we have 51 1.5 wiz * not received an acknowledgement within a reasonable amount 52 1.1 cgd * of time 53 1.1 cgd */ 54 1.4 lukem void 55 1.11 joerg ctl_transact(struct in_addr target, CTL_MSG tmsg, int type, CTL_RESPONSE *rp) 56 1.1 cgd { 57 1.6 mycroft struct pollfd set[1]; 58 1.4 lukem int nready, cc; 59 1.1 cgd 60 1.4 lukem nready = 0; 61 1.10 lukem tmsg.type = type; 62 1.1 cgd daemon_addr.sin_addr = target; 63 1.1 cgd daemon_addr.sin_port = daemon_port; 64 1.6 mycroft set[0].fd = ctl_sockt; 65 1.6 mycroft set[0].events = POLLIN; 66 1.1 cgd 67 1.1 cgd /* 68 1.1 cgd * Keep sending the message until a response of 69 1.1 cgd * the proper type is obtained. 70 1.1 cgd */ 71 1.1 cgd do { 72 1.1 cgd /* resend message until a response is obtained */ 73 1.1 cgd do { 74 1.10 lukem cc = sendto(ctl_sockt, (char *)&tmsg, sizeof (tmsg), 0, 75 1.1 cgd (struct sockaddr *)&daemon_addr, 76 1.1 cgd sizeof (daemon_addr)); 77 1.10 lukem if (cc != sizeof (tmsg)) { 78 1.1 cgd if (errno == EINTR) 79 1.1 cgd continue; 80 1.1 cgd p_error("Error on write to talk daemon"); 81 1.1 cgd } 82 1.6 mycroft nready = poll(set, 1, CTL_WAIT * 1000); 83 1.1 cgd if (nready < 0) { 84 1.1 cgd if (errno == EINTR) 85 1.1 cgd continue; 86 1.1 cgd p_error("Error waiting for daemon response"); 87 1.1 cgd } 88 1.1 cgd } while (nready == 0); 89 1.1 cgd /* 90 1.1 cgd * Keep reading while there are queued messages 91 1.1 cgd * (this is not necessary, it just saves extra 92 1.1 cgd * request/acknowledgements being sent) 93 1.1 cgd */ 94 1.1 cgd do { 95 1.1 cgd cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); 96 1.1 cgd if (cc < 0) { 97 1.1 cgd if (errno == EINTR) 98 1.1 cgd continue; 99 1.1 cgd p_error("Error on read from talk daemon"); 100 1.1 cgd } 101 1.1 cgd /* an immediate poll */ 102 1.6 mycroft nready = poll(set, 1, 0); 103 1.1 cgd } while (nready > 0 && (rp->vers != TALK_VERSION || 104 1.1 cgd rp->type != type)); 105 1.1 cgd } while (rp->vers != TALK_VERSION || rp->type != type); 106 1.1 cgd rp->id_num = ntohl(rp->id_num); 107 1.1 cgd rp->addr.sa_family = ntohs(rp->addr.sa_family); 108 1.1 cgd } 109