install C version of _doprnt
[unix-history] / usr / src / lib / libc / net / res_send.c
index afb74dd..36b23fe 100644 (file)
@@ -1,13 +1,18 @@
-
 /*
  * Copyright (c) 1985 Regents of the University of California.
 /*
  * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)res_send.c 6.17 (Berkeley) %G%";
-#endif LIBC_SCCS and not lint
+static char sccsid[] = "@(#)res_send.c 6.19 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
 
 /*
  * Send query to name server and wait for reply.
 
 /*
  * Send query to name server and wait for reply.
@@ -48,7 +53,7 @@ res_send(buf, buflen, answer, anslen)
 {
        register int n;
        int retry, v_circuit, resplen, ns;
 {
        register int n;
        int retry, v_circuit, resplen, ns;
-       int gotsomewhere = 0;
+       int gotsomewhere = 0, connected = 0;
        u_short id, len;
        char *cp;
        fd_set dsmask;
        u_short id, len;
        char *cp;
        fd_set dsmask;
@@ -57,6 +62,7 @@ res_send(buf, buflen, answer, anslen)
        HEADER *anhp = (HEADER *) answer;
        struct iovec iov[2];
        int terrno = ETIMEDOUT;
        HEADER *anhp = (HEADER *) answer;
        struct iovec iov[2];
        int terrno = ETIMEDOUT;
+       char junk[512];
 
 #ifdef DEBUG
        if (_res.options & RES_DEBUG) {
 
 #ifdef DEBUG
        if (_res.options & RES_DEBUG) {
@@ -78,9 +84,11 @@ res_send(buf, buflen, answer, anslen)
 #ifdef DEBUG
                if (_res.options & RES_DEBUG)
                        printf("Querying server (# %d) address = %s\n", ns+1,
 #ifdef DEBUG
                if (_res.options & RES_DEBUG)
                        printf("Querying server (# %d) address = %s\n", ns+1,
-                             inet_ntoa(_res.nsaddr_list[ns].sin_addr.s_addr));
+                             inet_ntoa(_res.nsaddr_list[ns].sin_addr));
 #endif DEBUG
                if (v_circuit) {
 #endif DEBUG
                if (v_circuit) {
+                       int truncated = 0;
+
                        /*
                         * Use virtual circuit.
                         */
                        /*
                         * Use virtual circuit.
                         */
@@ -145,7 +153,15 @@ res_send(buf, buflen, answer, anslen)
                                continue;
                        }
                        cp = answer;
                                continue;
                        }
                        cp = answer;
-                       resplen = len = ntohs(*(u_short *)cp);
+                       if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
+#ifdef DEBUG
+                               if (_res.options & RES_DEBUG)
+                                       fprintf(stderr, "response truncated\n");
+#endif DEBUG
+                               len = anslen;
+                               truncated = 1;
+                       } else
+                               len = resplen;
                        while (len != 0 &&
                           (n = read(s, (char *)cp, (int)len)) > 0) {
                                cp += n;
                        while (len != 0 &&
                           (n = read(s, (char *)cp, (int)len)) > 0) {
                                cp += n;
@@ -161,6 +177,22 @@ res_send(buf, buflen, answer, anslen)
                                s = -1;
                                continue;
                        }
                                s = -1;
                                continue;
                        }
+                       if (truncated) {
+                               /*
+                                * Flush rest of answer
+                                * so connection stays in synch.
+                                */
+                               anhp->tc = 1;
+                               len = resplen - anslen;
+                               while (len != 0) {
+                                       n = (len > sizeof(junk) ?
+                                           sizeof(junk) : len);
+                                       if ((n = read(s, junk, n)) > 0)
+                                               len -= n;
+                                       else
+                                               break;
+                               }
+                       }
                } else {
                        /*
                         * Use datagrams.
                } else {
                        /*
                         * Use datagrams.
@@ -174,12 +206,21 @@ res_send(buf, buflen, answer, anslen)
                                 * still receive a response
                                 * from another server.
                                 */
                                 * still receive a response
                                 * from another server.
                                 */
-                               if (connect(s, &_res.nsaddr_list[ns],
-                                   sizeof(struct sockaddr)) < 0 ||
-                                   send(s, buf, buflen, 0) != buflen) {
+                               if (connected == 0) {
+                                       if (connect(s, &_res.nsaddr_list[ns],
+                                           sizeof(struct sockaddr)) < 0) {
+#ifdef DEBUG
+                                               if (_res.options & RES_DEBUG)
+                                                       perror("connect");
+#endif DEBUG
+                                               continue;
+                                       }
+                                       connected = 1;
+                               }
+                               if (send(s, buf, buflen, 0) != buflen) {
 #ifdef DEBUG
                                        if (_res.options & RES_DEBUG)
 #ifdef DEBUG
                                        if (_res.options & RES_DEBUG)
-                                               perror("connect");
+                                               perror("send");
 #endif DEBUG
                                        continue;
                                }
 #endif DEBUG
                                        continue;
                                }
@@ -226,9 +267,11 @@ wait:
                                 * Disconnect if we want to listen
                                 * for responses from more than one server.
                                 */
                                 * Disconnect if we want to listen
                                 * for responses from more than one server.
                                 */
-                               if (_res.nscount > 1 && retry == _res.retry)
+                               if (_res.nscount > 1 && connected) {
                                        (void) connect(s, &no_addr,
                                            sizeof(no_addr));
                                        (void) connect(s, &no_addr,
                                            sizeof(no_addr));
+                                       connected = 0;
+                               }
                                gotsomewhere = 1;
                                continue;
                        }
                                gotsomewhere = 1;
                                continue;
                        }