|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)ctl_transact.c 5.7 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include "talk_ctl.h" ! 25: #include <sys/time.h> ! 26: ! 27: #define CTL_WAIT 2 /* time to wait for a response, in seconds */ ! 28: ! 29: /* ! 30: * SOCKDGRAM is unreliable, so we must repeat messages if we have ! 31: * not recieved an acknowledgement within a reasonable amount ! 32: * of time ! 33: */ ! 34: ctl_transact(target, msg, type, rp) ! 35: struct in_addr target; ! 36: CTL_MSG msg; ! 37: int type; ! 38: CTL_RESPONSE *rp; ! 39: { ! 40: int read_mask, ctl_mask, nready, cc; ! 41: struct timeval wait; ! 42: ! 43: msg.type = type; ! 44: daemon_addr.sin_addr = target; ! 45: daemon_addr.sin_port = daemon_port; ! 46: ctl_mask = 1 << ctl_sockt; ! 47: ! 48: /* ! 49: * Keep sending the message until a response of ! 50: * the proper type is obtained. ! 51: */ ! 52: do { ! 53: wait.tv_sec = CTL_WAIT; ! 54: wait.tv_usec = 0; ! 55: /* resend message until a response is obtained */ ! 56: do { ! 57: cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0, ! 58: &daemon_addr, sizeof (daemon_addr)); ! 59: if (cc != sizeof (msg)) { ! 60: if (errno == EINTR) ! 61: continue; ! 62: p_error("Error on write to talk daemon"); ! 63: } ! 64: read_mask = ctl_mask; ! 65: nready = select(32, &read_mask, 0, 0, &wait); ! 66: if (nready < 0) { ! 67: if (errno == EINTR) ! 68: continue; ! 69: p_error("Error waiting for daemon response"); ! 70: } ! 71: } while (nready == 0); ! 72: /* ! 73: * Keep reading while there are queued messages ! 74: * (this is not necessary, it just saves extra ! 75: * request/acknowledgements being sent) ! 76: */ ! 77: do { ! 78: cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); ! 79: if (cc < 0) { ! 80: if (errno == EINTR) ! 81: continue; ! 82: p_error("Error on read from talk daemon"); ! 83: } ! 84: read_mask = ctl_mask; ! 85: /* an immediate poll */ ! 86: timerclear(&wait); ! 87: nready = select(32, &read_mask, 0, 0, &wait); ! 88: } while (nready > 0 && (rp->vers != TALK_VERSION || ! 89: rp->type != type)); ! 90: } while (rp->vers != TALK_VERSION || rp->type != type); ! 91: rp->id_num = ntohl(rp->id_num); ! 92: rp->addr.sa_family = ntohs(rp->addr.sa_family); ! 93: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.