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