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