122389Sdist /* 2*62301Sbostic * Copyright (c) 1983, 1993 3*62301Sbostic * The Regents of the University of California. All rights reserved. 434373Sbostic * 542770Sbostic * %sccs.include.redist.c% 622389Sdist */ 722389Sdist 816363Skarels #ifndef lint 9*62301Sbostic static char sccsid[] = "@(#)ctl_transact.c 8.1 (Berkeley) 06/06/93"; 1034373Sbostic #endif /* not lint */ 1116363Skarels 1246858Sbostic #include <sys/types.h> 1346858Sbostic #include <sys/socket.h> 1446858Sbostic #include <sys/time.h> 1546858Sbostic #include <netinet/in.h> 1646858Sbostic #include <protocols/talkd.h> 1746858Sbostic #include <errno.h> 1816345Skarels #include "talk_ctl.h" 1916345Skarels 2016363Skarels #define CTL_WAIT 2 /* time to wait for a response, in seconds */ 2116345Skarels 2216363Skarels /* 2316363Skarels * SOCKDGRAM is unreliable, so we must repeat messages if we have 2416363Skarels * not recieved an acknowledgement within a reasonable amount 2516363Skarels * of time 2616363Skarels */ 2726846Smckusick ctl_transact(target, msg, type, rp) 2816363Skarels struct in_addr target; 2916363Skarels CTL_MSG msg; 3016363Skarels int type; 3126846Smckusick CTL_RESPONSE *rp; 3216345Skarels { 3326846Smckusick int read_mask, ctl_mask, nready, cc; 3416363Skarels struct timeval wait; 3516345Skarels 3616363Skarels msg.type = type; 3716363Skarels daemon_addr.sin_addr = target; 3816363Skarels daemon_addr.sin_port = daemon_port; 3916363Skarels ctl_mask = 1 << ctl_sockt; 4016345Skarels 4116345Skarels /* 4226846Smckusick * Keep sending the message until a response of 4326846Smckusick * the proper type is obtained. 4416345Skarels */ 4516345Skarels do { 4621905Sbloom wait.tv_sec = CTL_WAIT; 4721905Sbloom wait.tv_usec = 0; 4826846Smckusick /* resend message until a response is obtained */ 4916363Skarels do { 5026846Smckusick cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0, 5146858Sbostic (struct sockaddr *)&daemon_addr, 5246858Sbostic sizeof (daemon_addr)); 5326846Smckusick if (cc != sizeof (msg)) { 5416363Skarels if (errno == EINTR) 5516363Skarels continue; 5616363Skarels p_error("Error on write to talk daemon"); 5716363Skarels } 5816363Skarels read_mask = ctl_mask; 5926846Smckusick nready = select(32, &read_mask, 0, 0, &wait); 6026846Smckusick if (nready < 0) { 6116363Skarels if (errno == EINTR) 6216363Skarels continue; 6316363Skarels p_error("Error waiting for daemon response"); 6416363Skarels } 6516363Skarels } while (nready == 0); 6626846Smckusick /* 6726846Smckusick * Keep reading while there are queued messages 6826846Smckusick * (this is not necessary, it just saves extra 6926846Smckusick * request/acknowledgements being sent) 7016363Skarels */ 7116363Skarels do { 7226846Smckusick cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); 7316363Skarels if (cc < 0) { 7416363Skarels if (errno == EINTR) 7516363Skarels continue; 7616363Skarels p_error("Error on read from talk daemon"); 7716363Skarels } 7816363Skarels read_mask = ctl_mask; 7916363Skarels /* an immediate poll */ 8016363Skarels timerclear(&wait); 8116363Skarels nready = select(32, &read_mask, 0, 0, &wait); 8226846Smckusick } while (nready > 0 && (rp->vers != TALK_VERSION || 8326846Smckusick rp->type != type)); 8426846Smckusick } while (rp->vers != TALK_VERSION || rp->type != type); 8526846Smckusick rp->id_num = ntohl(rp->id_num); 8626846Smckusick rp->addr.sa_family = ntohs(rp->addr.sa_family); 8716345Skarels } 88