📄 send.c
字号:
_res_perror("send"); (void) close(sock); return(-1); }/* * Wait for the arrival of a reply, timeout, or error message. */wait: n = recvsock(sock, answer, anslen); if (n <= 0) { if (bitset(RES_DEBUG, _res.options)) _res_perror("recvfrom"); (void) close(sock); return(-1); }/* * Make sure it is the proper response by checking the packet id. */ if (qp->id != bp->id) { if (bitset(RES_DEBUG, _res.options)) { printf("old answer:\n"); fp_query(answer, stdout); } goto wait; }/* * Never leave the socket open. */ (void) close(sock); return(n);}#endif /*HOST_RES_SEND*//*** _RES_CONNECT -- Connect to a stream (virtual circuit) socket** ------------------------------------------------------------**** Returns:** 0 if successfully connected.** -1 in case of failure or timeout.**** Note that we use _res.retrans to override the default** connect timeout value.*/static jmp_buf timer_buf;static sigtype_t/*ARGSUSED*/timer(sig)int sig;{ longjmp(timer_buf, 1);}int_res_connect(sock, addr, addrlen)input int sock;input struct sockaddr_in *addr; /* the server address to connect to */input int addrlen;{ if (setjmp(timer_buf) != 0) { errno = ETIMEDOUT; setalarm(0); return(-1); } (void) signal(SIGALRM, timer); setalarm(_res.retrans); if (connect(sock, (struct sockaddr *)addr, addrlen) < 0) { if (errno == EINTR) errno = ETIMEDOUT; setalarm(0); return(-1); } setalarm(0); return(0);}/*** _RES_WRITE -- Write the query buffer via a stream socket** --------------------------------------------------------**** Returns:** Length of buffer if successfully transmitted.** -1 in case of failure (error message is issued).**** The query is sent in two steps: first a single word with** the length of the buffer, followed by the buffer itself.*/int_res_write(sock, buf, bufsize)input int sock;input char *buf; /* address of formatted query buffer */input int bufsize; /* length of query buffer */{ u_short len;/* * Write the length of the query buffer. */ len = htons(bufsize); if (write(sock, (char *)&len, sizeof(len)) != sizeof(len)) { _res_perror("write query length"); return(-1); }/* * Write the query buffer itself. */ if (write(sock, buf, bufsize) != bufsize) { _res_perror("write query"); return(-1); } return(bufsize);}/*** _RES_READ -- Read the answer buffer via a stream socket** -------------------------------------------------------**** Returns:** Length of buffer if successfully received.** -1 in case of failure (error message is issued).**** The answer is read in two steps: first a single word which** gives the length of the buffer, followed by the buffer itself.** If the answer is too long to fit into the supplied buffer,** only the portion that fits will be stored, the residu will be** flushed, and the truncation flag will be set.*/int_res_read(sock, buf, bufsize)input int sock;output char *buf; /* address of buffer to store answer */input int bufsize; /* maximum size of answer buffer */{ u_short len; char *buffer; int buflen; int reslen; register int n; /* set stream timeout for recvsock */ timeout = 60;/* * Read the length of answer buffer. */ buffer = (char *)&len; buflen = sizeof(len); while (buflen > 0 && (n = recvsock(sock, buffer, buflen)) > 0) { buffer += n; buflen -= n; } if (buflen != 0) { _res_perror("read answer length"); return(-1); }/* * Terminate if length is zero. */ len = ntohs(len); if (len == 0) return(0);/* * Check for truncation. */ reslen = 0; if ((int)len > bufsize) { reslen = len - bufsize; len = bufsize; }/* * Read the answer buffer itself. */ buffer = buf; buflen = len; while (buflen > 0 && (n = recvsock(sock, buffer, buflen)) > 0) { buffer += n; buflen -= n; } if (buflen != 0) { _res_perror("read answer"); return(-1); }/* * Discard the residu to keep connection in sync. */ if (reslen > 0) { HEADER *bp = (HEADER *)buf; char resbuf[PACKETSZ]; buffer = resbuf; buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf); while (reslen > 0 && (n = recvsock(sock, buffer, buflen)) > 0) { reslen -= n; buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf); } if (reslen != 0) { _res_perror("read residu"); return(-1); } if (bitset(RES_DEBUG, _res.options)) (void) fprintf(stderr, "response truncated\n"); /* set truncation flag */ bp->tc = 1; } return(len);}/*** RECVSOCK -- Read from stream or datagram socket with timeout** ------------------------------------------------------------**** Returns:** Length of buffer if successfully received.** -1 in case of failure or timeout.**** Inputs:** The global variable timeout should have been** set with the desired timeout value in seconds.*/static intrecvsock(sock, buffer, buflen)input int sock;output char *buffer; /* current buffer address */input int buflen; /* remaining buffer size */{ fd_set fds; struct timeval wait; register int n; wait.tv_sec = timeout; wait.tv_usec = 0; /* FD_ZERO(&fds); */ bzero((char *)&fds, sizeof(fds)); FD_SET(sock, &fds);/* * Wait for the arrival of data, or timeout. */ n = select(FD_SETSIZE, &fds, (fd_set *)NULL, (fd_set *)NULL, &wait); if (n <= 0) { if (n == 0) errno = ETIMEDOUT; return(-1); }/* * Fake an error if nothing was actually read. */ n = recv(sock, buffer, buflen, 0); if (n == 0) errno = ECONNRESET; return(n);}/*** _RES_PERROR -- Issue perror message including host info** -------------------------------------------------------**** Returns:** None.**** The address and name of the server host must be set** in advance via _res_setaddr().*/static struct in_addr curaddr; /* current address of server host */static char *curhost = NULL; /* current name of server host */void_res_setaddr(sin, host)input struct sockaddr_in *sin; /* address of host to connect to */input char *host; /* name of host to connect to */{ curaddr = sin->sin_addr; curhost = host;}void_res_perror(message)input char *message; /* perror message string */{ int save_errno; save_errno = errno; if (curaddr.s_addr) (void) fprintf(stderr, "%s ", inet_ntoa(curaddr)); if (curhost) (void) fprintf(stderr, "(%s) ", curhost); errno = save_errno; perror(message);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -