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
32enum
33{
34 ACTION_MERGE = 0,
35 ACTION_CONTINUE,
36};
37
38static const char *
39family_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
52static const char *
53action_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
66static void
67do_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 (format: "***** 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 (format: "merge unexpectedly succeeded:\n %s\n", formatted);
93 support_record_failure ();
94 free (ptr: 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 (format: "continue failed:\n%s\n", formatted);
116 support_record_failure ();
117 }
118
119 free (ptr: formatted);
120 break;
121 }
122 default:
123 __builtin_unreachable ();
124 }
125}
126
127static void
128do_one_test_set (int action)
129{
130 char buf[32];
131
132 snprintf (s: buf, maxlen: sizeof (buf), format: "files [SUCCESS=%s] files",
133 action_str (action));
134 __nss_configure_lookup (dbname: "hosts", string: 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
141static int
142do_test (void)
143{
144 do_one_test_set (action: ACTION_CONTINUE);
145 do_one_test_set (action: ACTION_MERGE);
146 return 0;
147}
148
149#include <support/test-driver.c>
150

source code of glibc/nss/tst-nss-gai-actions.c