(root)/
glibc-2.38/
nss/
tst-nss-gai-actions.c
       1  /* Test continue and merge NSS actions for getaddrinfo.
       2     Copyright The GNU Toolchain Authors.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <dlfcn.h>
      20  #include <gnu/lib-names.h>
      21  #include <nss.h>
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <string.h>
      25  
      26  #include <support/check.h>
      27  #include <support/format_nss.h>
      28  #include <support/support.h>
      29  #include <support/xstdio.h>
      30  #include <support/xunistd.h>
      31  
      32  enum
      33  {
      34    ACTION_MERGE = 0,
      35    ACTION_CONTINUE,
      36  };
      37  
      38  static const char *
      39  family_str (int family)
      40  {
      41    switch (family)
      42      {
      43      case AF_UNSPEC:
      44        return "AF_UNSPEC";
      45      case AF_INET:
      46        return "AF_INET";
      47      default:
      48        __builtin_unreachable ();
      49      }
      50  }
      51  
      52  static const char *
      53  action_str (int action)
      54  {
      55    switch (action)
      56      {
      57      case ACTION_MERGE:
      58        return "merge";
      59      case ACTION_CONTINUE:
      60        return "continue";
      61      default:
      62        __builtin_unreachable ();
      63      }
      64  }
      65  
      66  static void
      67  do_one_test (int action, int family, bool canon)
      68  {
      69    struct addrinfo hints =
      70      {
      71        .ai_family = family,
      72      };
      73  
      74    struct addrinfo *ai;
      75  
      76    if (canon)
      77      hints.ai_flags = AI_CANONNAME;
      78  
      79    printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
      80  	  action_str (action), family_str (family),
      81  	  canon ? "AI_CANONNAME" : "");
      82  
      83    int ret = getaddrinfo ("example.org", "80", &hints, &ai);
      84  
      85    switch (action)
      86      {
      87      case ACTION_MERGE:
      88        if (ret == 0)
      89  	{
      90  	  char *formatted = support_format_addrinfo (ai, ret);
      91  
      92  	  printf ("merge unexpectedly succeeded:\n %s\n", formatted);
      93  	  support_record_failure ();
      94  	  free (formatted);
      95  	}
      96        else
      97  	return;
      98      case ACTION_CONTINUE:
      99  	{
     100  	  char *formatted = support_format_addrinfo (ai, ret);
     101  
     102  	  /* Verify that the result appears exactly once.  */
     103  	  const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
     104  	    "address: DGRAM/UDP 192.0.0.1 80\n"
     105  	    "address: RAW/IP 192.0.0.1 80\n";
     106  
     107  	  const char *contains = strstr (formatted, expected);
     108  	  const char *contains2 = NULL;
     109  
     110  	  if (contains != NULL)
     111  	    contains2 = strstr (contains + strlen (expected), expected);
     112  
     113  	  if (contains == NULL || contains2 != NULL)
     114  	    {
     115  	      printf ("continue failed:\n%s\n", formatted);
     116  	      support_record_failure ();
     117  	    }
     118  
     119  	  free (formatted);
     120  	  break;
     121  	}
     122      default:
     123        __builtin_unreachable ();
     124      }
     125  }
     126  
     127  static void
     128  do_one_test_set (int action)
     129  {
     130    char buf[32];
     131  
     132    snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
     133  	    action_str (action));
     134    __nss_configure_lookup ("hosts", buf);
     135  
     136    do_one_test (action, AF_UNSPEC, false);
     137    do_one_test (action, AF_INET, false);
     138    do_one_test (action, AF_INET, true);
     139  }
     140  
     141  static int
     142  do_test (void)
     143  {
     144    do_one_test_set (ACTION_CONTINUE);
     145    do_one_test_set (ACTION_MERGE);
     146    return 0;
     147  }
     148  
     149  #include <support/test-driver.c>