9cb1d306a33a77f38a9e3c40835cf2b04d326d11
[oweals/busybox.git] / libpwdgrp / pwd_grp_internal.c
1 /*  Copyright (C) 2003     Manuel Novoa III
2  *
3  *  Licensed under GPL v2, or later.  See file LICENSE in this tarball.
4  */
5
6 /*  Nov 6, 2003  Initial version.
7  *
8  *  NOTE: This implementation is quite strict about requiring all
9  *    field seperators.  It also does not allow leading whitespace
10  *    except when processing the numeric fields.  glibc is more
11  *    lenient.  See the various glibc difference comments below.
12  *
13  *  TODO:
14  *    Move to dynamic allocation of (currently statically allocated)
15  *      buffers; especially for the group-related functions since
16  *      large group member lists will cause error returns.
17  *
18  */
19
20 #include <features.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <stddef.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <ctype.h>
29
30 #include "pwd_.h"
31 #include "grp_.h"
32 #include "shadow_.h"
33 #include "libbb.h"
34
35 #ifndef _PATH_SHADOW
36 #define _PATH_SHADOW    "/etc/shadow"
37 #endif
38 #ifndef _PATH_PASSWD
39 #define _PATH_PASSWD    "/etc/passwd"
40 #endif
41 #ifndef _PATH_GROUP
42 #define _PATH_GROUP     "/etc/group"
43 #endif
44
45 /**********************************************************************/
46 /* Sizes for statically allocated buffers. */
47
48 /* If you change these values, also change _SC_GETPW_R_SIZE_MAX and
49  * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */
50 #define PWD_BUFFER_SIZE 256
51 #define GRP_BUFFER_SIZE 256
52
53 /**********************************************************************/
54 /* Prototypes for internal functions. */
55
56 extern int __parsepwent(void *pw, char *line);
57 extern int __parsegrent(void *gr, char *line);
58 extern int __parsespent(void *sp, char *line);
59
60 extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data,
61                                            char *__restrict line_buff, size_t buflen, FILE *f);
62
63
64 #ifndef GETXXKEY_R_FUNC
65 #error GETXXKEY_R_FUNC is not defined!
66 #endif
67 /**********************************************************************/
68 #ifdef GETXXKEY_R_FUNC
69
70 int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
71                                         GETXXKEY_R_ENTTYPE *__restrict resultbuf,
72                                         char *__restrict buffer, size_t buflen,
73                                         GETXXKEY_R_ENTTYPE **__restrict result)
74 {
75         FILE *stream;
76         int rv;
77
78         *result = NULL;
79
80         if (!(stream = fopen(DO_GETXXKEY_R_PATHNAME, "r"))) {
81                 rv = errno;
82         } else {
83                 do {
84                         if (!(rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf,
85                                                                    buffer, buflen, stream))
86                                 ) {
87                                 if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */
88                                         *result = resultbuf;
89                                         break;
90                                 }
91                         } else {
92                                 if (rv == ENOENT) {     /* end-of-file encountered. */
93                                         rv = 0;
94                                 }
95                                 break;
96                         }
97                 } while (1);
98                 fclose(stream);
99         }
100
101         return rv;
102 }
103
104 #endif
105 /**********************************************************************/
106 #undef GETXXKEY_R_FUNC
107 #undef GETXXKEY_R_PARSER
108 #undef GETXXKEY_R_ENTTYPE
109 #undef GETXXKEY_R_TEST
110 #undef DO_GETXXKEY_R_KEYTYPE
111 #undef DO_GETXXKEY_R_PATHNAME
112