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 15 #define CTL_WAIT 2 /* time to wait for a response, in seconds */ 16 17 /* 18 * SOCKDGRAM is unreliable, so we must repeat messages if we have 19 * not recieved an acknowledgement within a reasonable amount 20 * of time 21 */ 22 ctl_transact(target, msg, type, response) 23 struct in_addr target; 24 CTL_MSG msg; 25 int type; 26 CTL_RESPONSE *response; 27 { 28 struct sockaddr junk; 29 int read_mask; 30 int ctl_mask; 31 int nready; 32 int cc; 33 int junk_size; 34 struct timeval wait; 35 36 msg.type = type; 37 daemon_addr.sin_addr = target; 38 daemon_addr.sin_port = daemon_port; 39 ctl_mask = 1 << ctl_sockt; 40 41 /* 42 * keep sending the message until a response of the right 43 * type is obtained 44 */ 45 do { 46 wait.tv_sec = CTL_WAIT; 47 wait.tv_usec = 0; 48 49 /* keep sending the message until a response is obtained */ 50 do { 51 cc = sendto(ctl_sockt, (char *)&msg, sizeof(CTL_MSG), 0, 52 (struct sockaddr *)&daemon_addr, 53 sizeof(daemon_addr)); 54 if (cc != sizeof(CTL_MSG)) { 55 if (errno == EINTR) 56 continue; 57 p_error("Error on write to talk daemon"); 58 } 59 read_mask = ctl_mask; 60 if ((nready = select(32, &read_mask, 0, 0, &wait)) < 0) { 61 if (errno == EINTR) 62 continue; 63 p_error("Error waiting for daemon response"); 64 } 65 } while (nready == 0); 66 /* keep reading while there are queued messages 67 (this is not necessary, it just saves extra 68 request/acknowledgements being sent) 69 */ 70 do { 71 junk_size = sizeof(junk); 72 cc = recvfrom(ctl_sockt, (char *)response, 73 sizeof (CTL_RESPONSE), 0, &junk, &junk_size); 74 if (cc < 0) { 75 if (errno == EINTR) 76 continue; 77 p_error("Error on read from talk daemon"); 78 } 79 read_mask = ctl_mask; 80 /* an immediate poll */ 81 timerclear(&wait); 82 nready = select(32, &read_mask, 0, 0, &wait); 83 } while (nready > 0 && response->type != type); 84 } while (response->type != type); 85 } 86