]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hunt/huntd/ctl_transact.c
Yet Another Monster Commit:
[bsdgames-darwin.git] / hunt / huntd / ctl_transact.c
1 /* $NetBSD: ctl_transact.c,v 1.2 1997/10/10 16:33:01 lukem Exp $ */
2 /*
3 * Copyright (c) 1983 Regents of the University of California.
4 * All rights reserved. The Berkeley software License Agreement
5 * specifies the terms and conditions for redistribution.
6 */
7
8 #include "bsd.h"
9
10 #if defined(TALK_43) || defined(TALK_42)
11
12 #include <sys/cdefs.h>
13 #ifndef lint
14 #if 0
15 static char sccsid[] = "@(#)ctl_transact.c 5.2 (Berkeley) 3/13/86";
16 #else
17 __RCSID("$NetBSD: ctl_transact.c,v 1.2 1997/10/10 16:33:01 lukem Exp $");
18 #endif
19 #endif /* not lint */
20
21 #include <sys/time.h>
22 #include <unistd.h>
23 #include "hunt.h"
24 #include "talk_ctl.h"
25
26 #define CTL_WAIT 2 /* time to wait for a response, in seconds */
27 #define MAX_RETRY 5
28
29 /*
30 * SOCKDGRAM is unreliable, so we must repeat messages if we have
31 * not recieved an acknowledgement within a reasonable amount
32 * of time
33 */
34 void
35 ctl_transact(target, msg, type, rp)
36 struct in_addr target;
37 CTL_MSG msg;
38 int type;
39 CTL_RESPONSE *rp;
40 {
41 fd_set read_mask, ctl_mask;
42 int nready, cc, retries;
43 struct timeval wait;
44
45 nready = 0;
46 msg.type = type;
47 daemon_addr.sin_addr = target;
48 daemon_addr.sin_port = daemon_port;
49 FD_SET(ctl_sockt, &ctl_mask);
50
51 /*
52 * Keep sending the message until a response of
53 * the proper type is obtained.
54 */
55 do {
56 wait.tv_sec = CTL_WAIT;
57 wait.tv_usec = 0;
58 /* resend message until a response is obtained */
59 for (retries = MAX_RETRY; retries > 0; retries -= 1) {
60 cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
61 (struct sockaddr *)&daemon_addr, sizeof (daemon_addr));
62 if (cc != sizeof (msg)) {
63 if (errno == EINTR)
64 continue;
65 p_error("Error on write to talk daemon");
66 }
67 read_mask = ctl_mask;
68 nready = select(32, &read_mask, 0, 0, &wait);
69 if (nready < 0) {
70 if (errno == EINTR)
71 continue;
72 p_error("Error waiting for daemon response");
73 }
74 if (nready != 0)
75 break;
76 }
77 if (retries <= 0)
78 break;
79 /*
80 * Keep reading while there are queued messages
81 * (this is not necessary, it just saves extra
82 * request/acknowledgements being sent)
83 */
84 do {
85 cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
86 if (cc < 0) {
87 if (errno == EINTR)
88 continue;
89 p_error("Error on read from talk daemon");
90 }
91 read_mask = ctl_mask;
92 /* an immediate poll */
93 timerclear(&wait);
94 nready = select(32, &read_mask, 0, 0, &wait);
95 } while (nready > 0 && (
96 #ifdef TALK_43
97 rp->vers != TALK_VERSION ||
98 #endif
99 rp->type != type));
100 } while (
101 #ifdef TALK_43
102 rp->vers != TALK_VERSION ||
103 #endif
104 rp->type != type);
105 rp->id_num = ntohl(rp->id_num);
106 #ifdef TALK_43
107 rp->addr.sa_family = ntohs(rp->addr.sa_family);
108 # else
109 rp->addr.sin_family = ntohs(rp->addr.sin_family);
110 # endif
111 }
112 #endif