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 (struct sockaddr *)&daemon_addr, 52 sizeof(daemon_addr)); 53 if (cc != sizeof(CTL_MSG)) { 54 if (errno == EINTR) 55 continue; 56 p_error("Error on write to talk daemon"); 57 } 58 read_mask = ctl_mask; 59 if ((nready = select(32, &read_mask, 0, 0, &wait)) < 0) { 60 if (errno == EINTR) 61 continue; 62 p_error("Error waiting for daemon response"); 63 } 64 } while (nready == 0); 65 /* keep reading while there are queued messages 66 (this is not necessary, it just saves extra 67 request/acknowledgements being sent) 68 */ 69 do { 70 junk_size = sizeof(junk); 71 cc = recvfrom(ctl_sockt, (char *)response, 72 sizeof (CTL_RESPONSE), 0, &junk, &junk_size); 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); 82 } while (nready > 0 && response->type != type); 83 } while (response->type != type); 84 } 85