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 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