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