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