blob: d6483be84410d43309df92b8b487a2e861cf0c36
1 | /* vi: set sw=4 ts=4: */ |
2 | /* Copyright (C) 2003 Manuel Novoa III |
3 | * |
4 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
5 | */ |
6 | |
7 | /* Nov 6, 2003 Initial version. |
8 | * |
9 | * NOTE: This implementation is quite strict about requiring all |
10 | * field seperators. It also does not allow leading whitespace |
11 | * except when processing the numeric fields. glibc is more |
12 | * lenient. See the various glibc difference comments below. |
13 | * |
14 | * TODO: |
15 | * Move to dynamic allocation of (currently statically allocated) |
16 | * buffers; especially for the group-related functions since |
17 | * large group member lists will cause error returns. |
18 | */ |
19 | |
20 | #ifndef GETXXKEY_R_FUNC |
21 | #error GETXXKEY_R_FUNC is not defined! |
22 | #endif |
23 | |
24 | int GETXXKEY_R_FUNC(GETXXKEY_R_KEYTYPE key, |
25 | GETXXKEY_R_ENTTYPE *__restrict resultbuf, |
26 | char *__restrict buffer, size_t buflen, |
27 | GETXXKEY_R_ENTTYPE **__restrict result) |
28 | { |
29 | FILE *stream; |
30 | int rv; |
31 | |
32 | *result = NULL; |
33 | |
34 | stream = fopen_for_read(GETXXKEY_R_PATHNAME); |
35 | if (!stream) |
36 | return errno; |
37 | while (1) { |
38 | rv = bb__pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream); |
39 | if (!rv) { |
40 | if (GETXXKEY_R_TEST(resultbuf)) { /* found key? */ |
41 | *result = resultbuf; |
42 | break; |
43 | } |
44 | } else { |
45 | if (rv == ENOENT) { /* EOF encountered */ |
46 | rv = 0; |
47 | } |
48 | break; |
49 | } |
50 | } |
51 | fclose(stream); |
52 | |
53 | return rv; |
54 | } |
55 | |
56 | #undef GETXXKEY_R_FUNC |
57 | #undef GETXXKEY_R_PARSER |
58 | #undef GETXXKEY_R_ENTTYPE |
59 | #undef GETXXKEY_R_TEST |
60 | #undef GETXXKEY_R_KEYTYPE |
61 | #undef GETXXKEY_R_PATHNAME |
62 |