(root)/
glibc-2.38/
resolv/
ns_name_ntop.c
       1  /* Convert DNS domain names from network format to textual presentation format.
       2   * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
       3   * Copyright (c) 1996,1999 by Internet Software Consortium.
       4   *
       5   * Permission to use, copy, modify, and distribute this software for any
       6   * purpose with or without fee is hereby granted, provided that the above
       7   * copyright notice and this permission notice appear in all copies.
       8   *
       9   * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
      10   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11   * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
      12   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
      15   * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16   */
      17  
      18  #include <arpa/nameser.h>
      19  #include <errno.h>
      20  #include <shlib-compat.h>
      21  #include <stdbool.h>
      22  
      23  /* Thinking in noninternationalized US-ASCII (per the DNS spec), is
      24     this character special ("in need of quoting")?  */
      25  static inline bool
      26  special (int ch)
      27  {
      28    switch (ch)
      29      {
      30      case '"':
      31      case '.':
      32      case ';':
      33      case '\\':
      34      case '(':
      35      case ')':
      36        /* Special modifiers in zone files.  */
      37      case '@':
      38      case '$':
      39        return true;
      40      default:
      41        return false;
      42      }
      43  }
      44  
      45  /* Thinking in noninternationalized US-ASCII (per the DNS spec), is
      46     this character visible and not a space when printed?  */
      47  static inline bool
      48  printable (int ch)
      49  {
      50    return ch > 0x20 && ch < 0x7f;
      51  }
      52  
      53  /* Converts an uncompressed, encoded domain name to printable ASCII as
      54     per RFC1035.  Returns the number of bytes written to buffer, or -1
      55     (with errno set).  The root is returned as "."  All other domains
      56     are returned in non absolute form.  */
      57  int
      58  ___ns_name_ntop (const unsigned char *src, char *dst, size_t dstsiz)
      59  {
      60    const unsigned char *cp;
      61    char *dn, *eom;
      62    unsigned char c;
      63    int l;
      64  
      65    cp = src;
      66    dn = dst;
      67    eom = dst + dstsiz;
      68  
      69    while ((l = *cp++) != 0)
      70      {
      71        if (l >= 64)
      72          {
      73            /* Some kind of compression pointer.  */
      74            __set_errno (EMSGSIZE);
      75            return -1;
      76          }
      77        if (dn != dst)
      78          {
      79            if (dn >= eom)
      80              {
      81                __set_errno (EMSGSIZE);
      82                return -1;
      83              }
      84            *dn++ = '.';
      85          }
      86        for (; l > 0; l--)
      87          {
      88            c = *cp++;
      89            if (special (c))
      90              {
      91                if (eom - dn < 2)
      92                  {
      93                    __set_errno (EMSGSIZE);
      94                    return -1;
      95                  }
      96                *dn++ = '\\';
      97                *dn++ = c;
      98              }
      99            else if (!printable (c))
     100              {
     101                if (eom - dn < 4)
     102                  {
     103                    __set_errno (EMSGSIZE);
     104                    return -1;
     105                  }
     106                *dn++ = '\\';
     107                *dn++ = '0' + (c / 100);
     108                *dn++ = '0' + ((c % 100) / 10);
     109                *dn++ = '0' + (c % 10);
     110              }
     111            else
     112              {
     113                if (eom - dn < 2)
     114                  {
     115                    __set_errno (EMSGSIZE);
     116                    return -1;
     117                  }
     118                *dn++ = c;
     119              }
     120          }
     121      }
     122    if (dn == dst)
     123      {
     124        if (dn >= eom)
     125          {
     126            __set_errno (EMSGSIZE);
     127            return -1;
     128          }
     129        *dn++ = '.';
     130      }
     131    if (dn >= eom)
     132      {
     133        __set_errno (EMSGSIZE);
     134        return -1;
     135      }
     136    *dn++ = '\0';
     137    return dn - dst;
     138  }
     139  versioned_symbol (libc, ___ns_name_ntop, ns_name_ntop, GLIBC_2_34);
     140  versioned_symbol (libc, ___ns_name_ntop, __ns_name_ntop, GLIBC_PRIVATE);
     141  libc_hidden_ver (___ns_name_ntop, __ns_name_ntop)
     142  
     143  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_9, GLIBC_2_34)
     144  compat_symbol (libresolv, ___ns_name_ntop, ns_name_ntop, GLIBC_2_9);
     145  #endif