1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)ctl_transact.c 5.7 (Berkeley) 06/01/90"; 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, rp) 23 struct in_addr target; 24 CTL_MSG msg; 25 int type; 26 CTL_RESPONSE *rp; 27 { 28 int read_mask, ctl_mask, nready, cc; 29 struct timeval wait; 30 31 msg.type = type; 32 daemon_addr.sin_addr = target; 33 daemon_addr.sin_port = daemon_port; 34 ctl_mask = 1 << ctl_sockt; 35 36 /* 37 * Keep sending the message until a response of 38 * the proper type is obtained. 39 */ 40 do { 41 wait.tv_sec = CTL_WAIT; 42 wait.tv_usec = 0; 43 /* resend message until a response is obtained */ 44 do { 45 cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0, 46 &daemon_addr, sizeof (daemon_addr)); 47 if (cc != sizeof (msg)) { 48 if (errno == EINTR) 49 continue; 50 p_error("Error on write to talk daemon"); 51 } 52 read_mask = ctl_mask; 53 nready = select(32, &read_mask, 0, 0, &wait); 54 if (nready < 0) { 55 if (errno == EINTR) 56 continue; 57 p_error("Error waiting for daemon response"); 58 } 59 } while (nready == 0); 60 /* 61 * Keep reading while there are queued messages 62 * (this is not necessary, it just saves extra 63 * request/acknowledgements being sent) 64 */ 65 do { 66 cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); 67 if (cc < 0) { 68 if (errno == EINTR) 69 continue; 70 p_error("Error on read from talk daemon"); 71 } 72 read_mask = ctl_mask; 73 /* an immediate poll */ 74 timerclear(&wait); 75 nready = select(32, &read_mask, 0, 0, &wait); 76 } while (nready > 0 && (rp->vers != TALK_VERSION || 77 rp->type != type)); 78 } while (rp->vers != TALK_VERSION || rp->type != type); 79 rp->id_num = ntohl(rp->id_num); 80 rp->addr.sa_family = ntohs(rp->addr.sa_family); 81 } 82