|
|
1.1 ! root 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: #include "bsd.h" ! 8: ! 9: #if defined(TALK_43) || defined(TALK_42) ! 10: ! 11: #ifndef lint ! 12: static char sccsid[] = "@(#)ctl_transact.c 5.2 (Berkeley) 3/13/86"; ! 13: #endif not lint ! 14: ! 15: #include "talk_ctl.h" ! 16: #include <sys/time.h> ! 17: ! 18: #define CTL_WAIT 2 /* time to wait for a response, in seconds */ ! 19: #define MAX_RETRY 5 ! 20: ! 21: /* ! 22: * SOCKDGRAM is unreliable, so we must repeat messages if we have ! 23: * not recieved an acknowledgement within a reasonable amount ! 24: * of time ! 25: */ ! 26: ctl_transact(target, msg, type, rp) ! 27: struct in_addr target; ! 28: CTL_MSG msg; ! 29: int type; ! 30: CTL_RESPONSE *rp; ! 31: { ! 32: int read_mask, ctl_mask, nready, cc, retries; ! 33: struct timeval wait; ! 34: ! 35: msg.type = type; ! 36: daemon_addr.sin_addr = target; ! 37: daemon_addr.sin_port = daemon_port; ! 38: ctl_mask = 1 << ctl_sockt; ! 39: ! 40: /* ! 41: * Keep sending the message until a response of ! 42: * the proper type is obtained. ! 43: */ ! 44: do { ! 45: wait.tv_sec = CTL_WAIT; ! 46: wait.tv_usec = 0; ! 47: /* resend message until a response is obtained */ ! 48: for (retries = MAX_RETRY; retries > 0; retries -= 1) { ! 49: cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0, ! 50: &daemon_addr, sizeof (daemon_addr)); ! 51: if (cc != sizeof (msg)) { ! 52: if (errno == EINTR) ! 53: continue; ! 54: p_error("Error on write to talk daemon"); ! 55: } ! 56: read_mask = ctl_mask; ! 57: nready = select(32, &read_mask, 0, 0, &wait); ! 58: if (nready < 0) { ! 59: if (errno == EINTR) ! 60: continue; ! 61: p_error("Error waiting for daemon response"); ! 62: } ! 63: if (nready != 0) ! 64: break; ! 65: } ! 66: if (retries <= 0) ! 67: break; ! 68: /* ! 69: * Keep reading while there are queued messages ! 70: * (this is not necessary, it just saves extra ! 71: * request/acknowledgements being sent) ! 72: */ ! 73: do { ! 74: cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0); ! 75: if (cc < 0) { ! 76: if (errno == EINTR) ! 77: continue; ! 78: p_error("Error on read from talk daemon"); ! 79: } ! 80: read_mask = ctl_mask; ! 81: /* an immediate poll */ ! 82: timerclear(&wait); ! 83: nready = select(32, &read_mask, 0, 0, &wait); ! 84: } while (nready > 0 && ( ! 85: #ifdef TALK_43 ! 86: rp->vers != TALK_VERSION || ! 87: #endif ! 88: rp->type != type)); ! 89: } while ( ! 90: #ifdef TALK_43 ! 91: rp->vers != TALK_VERSION || ! 92: #endif ! 93: rp->type != type); ! 94: rp->id_num = ntohl(rp->id_num); ! 95: #ifdef TALK_43 ! 96: rp->addr.sa_family = ntohs(rp->addr.sa_family); ! 97: # else ! 98: rp->addr.sin_family = ntohs(rp->addr.sin_family); ! 99: # endif ! 100: } ! 101: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.