]>
git.ipfire.org Git - thirdparty/glibc.git/blob - nss/nss_action_parse.c
1a7643a88423039b5a2695ee8b6354ad7afe83e8
1 /* Parse a service line from nsswitch.conf.
2 Copyright (c) 1996-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include "nss_action.h"
20 #include "nss_module.h"
26 /* Staging area during parsing. */
27 #define DYNARRAY_STRUCT action_list
28 #define DYNARRAY_ELEMENT struct nss_action
29 #define DYNARRAY_PREFIX action_list_
30 #include <malloc/dynarray-skeleton.c>
32 /* Skip whitespace in line[]. */
34 while (line[0] != '\0' && isspace (line[0])) \
37 /* Read the source names:
38 `( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
41 nss_action_parse (const char *line
, struct action_list
*result
)
47 /* No more sources specified. */
50 /* Read <source> identifier. */
51 const char *name
= line
;
52 while (line
[0] != '\0' && !isspace (line
[0]) && line
[0] != '[')
57 struct nss_action new_service
58 = { .module
= __nss_module_allocate (name
, line
- name
), };
59 if (new_service
.module
== NULL
)
61 /* Memory allocation error. */
62 action_list_mark_failed (result
);
65 nss_action_set_all (&new_service
, NSS_ACTION_CONTINUE
);
66 nss_action_set (&new_service
, NSS_STATUS_SUCCESS
, NSS_ACTION_RETURN
);
67 nss_action_set (&new_service
, NSS_STATUS_RETURN
, NSS_ACTION_RETURN
);
73 /* Read criterions. */
82 enum nss_status status
;
83 lookup_actions action
;
85 /* Grok ! before name to mean all statuses but that one. */
90 /* Read status name. */
92 while (line
[0] != '\0' && !isspace (line
[0]) && line
[0] != '='
96 /* Compare with known statuses. */
99 if (__strncasecmp (name
, "SUCCESS", 7) == 0)
100 status
= NSS_STATUS_SUCCESS
;
101 else if (__strncasecmp (name
, "UNAVAIL", 7) == 0)
102 status
= NSS_STATUS_UNAVAIL
;
106 else if (line
- name
== 8)
108 if (__strncasecmp (name
, "NOTFOUND", 8) == 0)
109 status
= NSS_STATUS_NOTFOUND
;
110 else if (__strncasecmp (name
, "TRYAGAIN", 8) == 0)
111 status
= NSS_STATUS_TRYAGAIN
;
126 while (line
[0] != '\0' && !isspace (line
[0]) && line
[0] != '='
130 if (line
- name
== 6 && __strncasecmp (name
, "RETURN", 6) == 0)
131 action
= NSS_ACTION_RETURN
;
132 else if (line
- name
== 8
133 && __strncasecmp (name
, "CONTINUE", 8) == 0)
134 action
= NSS_ACTION_CONTINUE
;
135 else if (line
- name
== 5
136 && __strncasecmp (name
, "MERGE", 5) == 0)
137 action
= NSS_ACTION_MERGE
;
143 /* Save the current action setting for this status,
144 set them all to the given action, and reset this one. */
145 const lookup_actions save
146 = nss_action_get (&new_service
, status
);
147 nss_action_set_all (&new_service
, action
);
148 nss_action_set (&new_service
, status
, save
);
151 nss_action_set (&new_service
, status
, action
);
155 while (line
[0] != ']');
161 action_list_add (result
, new_service
);
166 __nss_action_parse (const char *line
)
168 struct action_list list
;
169 action_list_init (&list
);
170 if (nss_action_parse (line
, &list
))
172 size_t size
= action_list_size (&list
);
173 nss_action_list result
174 = malloc (sizeof (*result
) * (size
+ 1));
177 action_list_free (&list
);
180 memcpy (result
, action_list_begin (&list
), sizeof (*result
) * size
);
182 result
[size
].module
= NULL
;
185 else if (action_list_has_failed (&list
))
187 /* Memory allocation error. */
188 __set_errno (ENOMEM
);
194 __set_errno (EINVAL
);