diff options
Diffstat (limited to 'nss/nss_files')
-rw-r--r-- | nss/nss_files/files-parse.c | 88 | ||||
-rw-r--r-- | nss/nss_files/files-sgrp.c | 38 |
2 files changed, 106 insertions, 20 deletions
diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c index 66615da26c..3603762f8e 100644 --- a/nss/nss_files/files-parse.c +++ b/nss/nss_files/files-parse.c @@ -103,6 +103,7 @@ parse_line (char *line, struct STRUCTURE *result, \ EXTRA_ARGS_DECL) \ { \ ENTDATA_DECL (data) \ + BUFFER_PREPARE \ char *p = strpbrk (line, EOLSET "\n"); \ if (p != NULL) \ *p = '\0'; \ @@ -127,6 +128,21 @@ nss_files_parse_hidden_def (parse_line) } \ } +# define STRING_LIST(variable, terminator_c) \ + { \ + char **list = parse_list (&line, buf_start, buf_end, terminator_c, \ + errnop); \ + if (list) \ + variable = list; \ + else \ + return -1; /* -1 indicates we ran out of space. */ \ + \ + /* Determine the new end of the buffer. */ \ + while (*list != NULL) \ + ++list; \ + buf_start = (char *) (list + 1); \ + } + /* Helper function. */ static inline uint32_t __attribute__ ((always_inline)) @@ -178,12 +194,39 @@ strtou32 (const char *nptr, char **endptr, int base) # ifndef TRAILING_LIST_MEMBER +# define BUFFER_PREPARE /* Nothing to do. */ # define TRAILING_LIST_PARSER /* Nothing to do. */ # else -# define TRAILING_LIST_PARSER \ +# define BUFFER_PREPARE \ + char *buf_start = NULL; \ + char *buf_end = (char *) data + datalen; \ + if (line >= data->linebuffer && line < buf_end) \ + /* Find the end of the line buffer, we will use the space in \ + DATA after it for storing the vector of pointers. */ \ + buf_start = strchr (line, '\0') + 1; \ + else \ + /* LINE does not point within DATA->linebuffer, so that space is \ + not being used for scratch space right now. We can use all of \ + it for the pointer vector storage. */ \ + buf_start = data->linebuffer; \ + +# define TRAILING_LIST_PARSER \ { \ - char **list = parse_list (line, data, datalen, errnop); \ + if (buf_start == NULL) \ + { \ + if (line >= data->linebuffer && line < buf_end) \ + /* Find the end of the line buffer, we will use the space in \ + DATA after it for storing the vector of pointers. */ \ + buf_start = strchr (line, '\0') + 1; \ + else \ + /* LINE does not point within DATA->linebuffer, so that space is \ + not being used for scratch space right now. We can use all of \ + it for the pointer vector storage. */ \ + buf_start = data->linebuffer; \ + } \ + \ + char **list = parse_list (&line, buf_start, buf_end, '\0', errnop); \ if (list) \ result->TRAILING_LIST_MEMBER = list; \ else \ @@ -192,19 +235,12 @@ strtou32 (const char *nptr, char **endptr, int base) static inline char ** __attribute ((always_inline)) -parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop) +parse_list (char **linep, char *eol, char *buf_end, int terminator_c, + int *errnop) { - char *eol, **list, **p; - - if (line >= data->linebuffer && line < (char *) data + datalen) - /* Find the end of the line buffer, we will use the space in DATA after - it for storing the vector of pointers. */ - eol = strchr (line, '\0') + 1; - else - /* LINE does not point within DATA->linebuffer, so that space is - not being used for scratch space right now. We can use all of - it for the pointer vector storage. */ - eol = data->linebuffer; + char *line = *linep; + char **list, **p; + /* Adjust the pointer so it is aligned for storing pointers. */ eol += __alignof__ (char *) - 1; eol -= (eol - (char *) 0) % __alignof__ (char *); @@ -214,25 +250,30 @@ parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop) p = list; while (1) { - char *elt; - - if ((size_t) ((char *) &p[1] - (char *) data) > datalen) + if ((char *) (p + 2) > buf_end) { /* We cannot fit another pointer in the buffer. */ *errnop = ERANGE; return NULL; } + if (*line == '\0') break; + if (*line == terminator_c) + { + ++line; + break; + } /* Skip leading white space. This might not be portable but useful. */ while (isspace (*line)) ++line; - elt = line; + char *elt = line; while (1) { - if (*line == '\0' || TRAILING_LIST_SEPARATOR_P (*line)) + if (*line == '\0' || *line == terminator_c + || TRAILING_LIST_SEPARATOR_P (*line)) { /* End of the next entry. */ if (line > elt) @@ -241,13 +282,20 @@ parse_list (char *line, struct parser_data *data, size_t datalen, int *errnop) /* Terminate string if necessary. */ if (*line != '\0') - *line++ = '\0'; + { + char endc = *line; + *line++ = '\0'; + if (endc == terminator_c) + goto out; + } break; } ++line; } } + out: *p = NULL; + *linep = line; return list; } diff --git a/nss/nss_files/files-sgrp.c b/nss/nss_files/files-sgrp.c new file mode 100644 index 0000000000..4e12cd83d4 --- /dev/null +++ b/nss/nss_files/files-sgrp.c @@ -0,0 +1,38 @@ +/* User file parser in nss_files module. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <gshadow.h> + +#define STRUCTURE sgrp +#define ENTNAME sgent +#define DATABASE "gshadow" +struct sgent_data {}; + +/* Our parser function is already defined in sgetspent_r.c, so use that + to parse lines from the database file. */ +#define EXTERN_PARSER +#include "files-parse.c" +#include GENERIC + +DB_LOOKUP (sgnam, 1 + strlen (name), (".%s", name), + { + if (name[0] != '+' && name[0] != '-' + && ! strcmp (name, result->sg_namp)) + break; + }, const char *name) |