optimization for normal masks requires keeping ptr to associated leaf,
[unix-history] / usr / src / usr.bin / talk / ctl_transact.c
CommitLineData
d0aeaf5a 1/*
725a8fbf
KB
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
f9ac90b4 4 *
cb956e54 5 * %sccs.include.redist.c%
d0aeaf5a
DF
6 */
7
963ce42e 8#ifndef lint
725a8fbf 9static char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) %G%";
f9ac90b4 10#endif /* not lint */
963ce42e 11
a4e94754
KB
12#include <sys/types.h>
13#include <sys/socket.h>
0328946e 14#include <sys/time.h>
a4e94754
KB
15#include <netinet/in.h>
16#include <protocols/talkd.h>
17#include <errno.h>
18#include "talk_ctl.h"
0328946e 19
963ce42e 20#define CTL_WAIT 2 /* time to wait for a response, in seconds */
0328946e 21
963ce42e
MK
22/*
23 * SOCKDGRAM is unreliable, so we must repeat messages if we have
24 * not recieved an acknowledgement within a reasonable amount
25 * of time
26 */
4fa2ac2d 27ctl_transact(target, msg, type, rp)
963ce42e
MK
28 struct in_addr target;
29 CTL_MSG msg;
30 int type;
4fa2ac2d 31 CTL_RESPONSE *rp;
0328946e 32{
4fa2ac2d 33 int read_mask, ctl_mask, nready, cc;
963ce42e
MK
34 struct timeval wait;
35
963ce42e
MK
36 msg.type = type;
37 daemon_addr.sin_addr = target;
38 daemon_addr.sin_port = daemon_port;
39 ctl_mask = 1 << ctl_sockt;
0328946e
MK
40
41 /*
4fa2ac2d
KM
42 * Keep sending the message until a response of
43 * the proper type is obtained.
0328946e 44 */
0328946e 45 do {
3f3b4df0
JB
46 wait.tv_sec = CTL_WAIT;
47 wait.tv_usec = 0;
4fa2ac2d 48 /* resend message until a response is obtained */
963ce42e 49 do {
4fa2ac2d 50 cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
a4e94754
KB
51 (struct sockaddr *)&daemon_addr,
52 sizeof (daemon_addr));
4fa2ac2d 53 if (cc != sizeof (msg)) {
963ce42e
MK
54 if (errno == EINTR)
55 continue;
56 p_error("Error on write to talk daemon");
57 }
58 read_mask = ctl_mask;
4fa2ac2d
KM
59 nready = select(32, &read_mask, 0, 0, &wait);
60 if (nready < 0) {
963ce42e
MK
61 if (errno == EINTR)
62 continue;
63 p_error("Error waiting for daemon response");
64 }
65 } while (nready == 0);
4fa2ac2d
KM
66 /*
67 * Keep reading while there are queued messages
68 * (this is not necessary, it just saves extra
69 * request/acknowledgements being sent)
963ce42e
MK
70 */
71 do {
4fa2ac2d 72 cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
963ce42e
MK
73 if (cc < 0) {
74 if (errno == EINTR)
75 continue;
76 p_error("Error on read from talk daemon");
77 }
78 read_mask = ctl_mask;
79 /* an immediate poll */
80 timerclear(&wait);
81 nready = select(32, &read_mask, 0, 0, &wait);
4fa2ac2d
KM
82 } while (nready > 0 && (rp->vers != TALK_VERSION ||
83 rp->type != type));
84 } while (rp->vers != TALK_VERSION || rp->type != type);
85 rp->id_num = ntohl(rp->id_num);
86 rp->addr.sa_family = ntohs(rp->addr.sa_family);
0328946e 87}