1 /*-
2 * Copyright (c) 1983, 1985
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)ctl_transact.c 5.1 (Berkeley) 6/6/85";
10 #endif not lint
11
12 #include "talk_ctl.h"
13 #include <sys/time.h>
14 #include <unistd.h>
15
16 #define CTL_WAIT 2 /* time to wait for a response, in seconds */
17
18 /*
19 * SOCKDGRAM is unreliable, so we must repeat messages if we have
20 * not recieved an acknowledgement within a reasonable amount
21 * of time
22 */
23 void
ctl_transact(target,msg,type,response)24 ctl_transact(target, msg, type, response)
25 struct in_addr target;
26 CTL_MSG msg;
27 int type;
28 CTL_RESPONSE *response;
29 {
30 struct sockaddr junk;
31 int read_mask;
32 int ctl_mask;
33 int nready;
34 int cc;
35 int junk_size;
36 struct timeval wait;
37
38 msg.type = type;
39 daemon_addr.sin_addr = target;
40 daemon_addr.sin_port = daemon_port;
41 ctl_mask = 1 << ctl_sockt;
42
43 /*
44 * keep sending the message until a response of the right
45 * type is obtained
46 */
47 do {
48 wait.tv_sec = CTL_WAIT;
49 wait.tv_usec = 0;
50
51 /* keep sending the message until a response is obtained */
52 do {
53 cc = sendto(ctl_sockt, (char *)&msg, sizeof(CTL_MSG), 0,
54 (struct sockaddr *)&daemon_addr,
55 sizeof(daemon_addr));
56 if (cc != sizeof(CTL_MSG)) {
57 if (errno == EINTR)
58 continue;
59 p_error("Error on write to talk daemon");
60 }
61 read_mask = ctl_mask;
62 if ((nready = select(32, (fd_set *)&read_mask, 0, 0, &wait)) < 0) {
63 if (errno == EINTR)
64 continue;
65 p_error("Error waiting for daemon response");
66 }
67 } while (nready == 0);
68 /* keep reading while there are queued messages
69 (this is not necessary, it just saves extra
70 request/acknowledgements being sent)
71 */
72 do {
73 junk_size = sizeof(junk);
74 cc = recvfrom(ctl_sockt, (char *)response,
75 sizeof (CTL_RESPONSE), 0, &junk, &junk_size);
76 if (cc < 0) {
77 if (errno == EINTR)
78 continue;
79 p_error("Error on read from talk daemon");
80 }
81 read_mask = ctl_mask;
82 /* an immediate poll */
83 timerclear(&wait);
84 nready = select(32, (fd_set *)&read_mask, 0, 0, &wait);
85 } while (nready > 0 && response->type != type);
86 } while (response->type != type);
87 }
88