OSDN Git Service

Yipe. uid and gid were reversed.
[android-x86/external-busybox.git] / libpwdgrp / __getgrent.c
1 /*
2  * __getgrent.c - This file is part of the libc-8086/grp package for ELKS,
3  * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
4  * 
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Library General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This 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  *  Library General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Library General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  */
20
21 #include "busybox.h" 
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "grp_.h"
27
28 /*
29  * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer
30  * so that lines of any length can be used.  On very very small systems,
31  * you may want to leave this undefined becasue it will make the grp functions
32  * somewhat larger (because of the inclusion of malloc and the code necessary).
33  * On larger systems, you will want to define this, because grp will _not_
34  * deal with long lines gracefully (they will be skipped).
35  */
36 #undef GR_SCALE_DYNAMIC
37
38 #ifndef GR_SCALE_DYNAMIC
39 /*
40  * If scaling is not dynamic, the buffers will be statically allocated, and
41  * maximums must be chosen.  GR_MAX_LINE_LEN is the maximum number of
42  * characters per line in the group file.  GR_MAX_MEMBERS is the maximum
43  * number of members of any given group.
44  */
45 #define GR_MAX_LINE_LEN 128
46 /* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */
47 #define GR_MAX_MEMBERS 11
48
49 #endif /* !GR_SCALE_DYNAMIC */
50
51
52 /*
53  * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate
54  * space for it's GID array before calling setgroups().  This is probably
55  * unnecessary scalage, so it's undefined by default.
56  */
57 #undef GR_DYNAMIC_GROUP_LIST
58
59 #ifndef GR_DYNAMIC_GROUP_LIST
60 /*
61  * GR_MAX_GROUPS is the size of the static array initgroups() uses for
62  * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined.
63  */
64 #define GR_MAX_GROUPS 64
65
66 #endif /* !GR_DYNAMIC_GROUP_LIST */
67
68
69 /*
70  * This is the core group-file read function.  It behaves exactly like
71  * getgrent() except that it is passed a file descriptor.  getgrent()
72  * is just a wrapper for this function.
73  */
74 struct group *__getgrent(int grp_fd)
75 {
76 #ifndef GR_SCALE_DYNAMIC
77         static char line_buff[GR_MAX_LINE_LEN];
78         static char *members[GR_MAX_MEMBERS];
79 #else
80         static char *line_buff = NULL;
81         static char **members = NULL;
82         short line_index;
83         short buff_size;
84 #endif
85         static struct group group;
86         register char *ptr;
87         char *field_begin;
88         short member_num;
89         char *endptr;
90         int line_len;
91
92
93         /* We use the restart label to handle malformatted lines */
94   restart:
95 #ifdef GR_SCALE_DYNAMIC
96         line_index = 0;
97         buff_size = 256;
98 #endif
99
100 #ifndef GR_SCALE_DYNAMIC
101         /* Read the line into the static buffer */
102         if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0)
103                 return NULL;
104         field_begin = strchr(line_buff, '\n');
105         if (field_begin != NULL)
106                 lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)),
107                           SEEK_CUR);
108         else {                                          /* The line is too long - skip it :-\ */
109
110                 do {
111                         if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0)
112                                 return NULL;
113                 } while (!(field_begin = strchr(line_buff, '\n')));
114                 lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1),
115                           SEEK_CUR);
116                 goto restart;
117         }
118         if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' ||
119                 *line_buff == '\t')
120                 goto restart;
121         *field_begin = '\0';
122
123 #else                                                   /* !GR_SCALE_DYNAMIC */
124         line_buff = realloc(line_buff, buff_size);
125         while (1) {
126                 if ((line_len = read(grp_fd, line_buff + line_index,
127                                                          buff_size - line_index)) <= 0)
128                         return NULL;
129                 field_begin = strchr(line_buff, '\n');
130                 if (field_begin != NULL) {
131                         lseek(grp_fd,
132                                   (long) (1 + field_begin -
133                                                   (line_len + line_index + line_buff)), SEEK_CUR);
134                         *field_begin = '\0';
135                         if (*line_buff == '#' || *line_buff == ' '
136                                 || *line_buff == '\n' || *line_buff == '\t')
137                                 goto restart;
138                         break;
139                 } else {                                /* Allocate some more space */
140
141                         line_index = buff_size;
142                         buff_size += 256;
143                         line_buff = realloc(line_buff, buff_size);
144                 }
145         }
146 #endif                                                  /* GR_SCALE_DYNAMIC */
147
148         /* Now parse the line */
149         group.gr_name = line_buff;
150         ptr = strchr(line_buff, ':');
151         if (ptr == NULL)
152                 goto restart;
153         *ptr++ = '\0';
154
155         group.gr_passwd = ptr;
156         ptr = strchr(ptr, ':');
157         if (ptr == NULL)
158                 goto restart;
159         *ptr++ = '\0';
160
161         field_begin = ptr;
162         ptr = strchr(ptr, ':');
163         if (ptr == NULL)
164                 goto restart;
165         *ptr++ = '\0';
166
167         group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10);
168         if (*endptr != '\0')
169                 goto restart;
170
171         member_num = 0;
172         field_begin = ptr;
173
174 #ifndef GR_SCALE_DYNAMIC
175         while ((ptr = strchr(ptr, ',')) != NULL) {
176                 *ptr = '\0';
177                 ptr++;
178                 members[member_num] = field_begin;
179                 field_begin = ptr;
180                 member_num++;
181         }
182         if (*field_begin == '\0')
183                 members[member_num] = NULL;
184         else {
185                 members[member_num] = field_begin;
186                 members[member_num + 1] = NULL;
187         }
188 #else                                                   /* !GR_SCALE_DYNAMIC */
189         if (members != NULL)
190             free(members);
191         members = (char **) malloc((member_num + 1) * sizeof(char *));   
192         for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) {
193             if ((ptr = strchr(field_begin, ',')) != NULL)
194                 *ptr++ = '\0';
195             members[member_num++] = field_begin;
196             members = (char **) realloc(members,
197                     (member_num + 1) * sizeof(char *));
198         }
199         members[member_num] = NULL;
200 #endif                                                  /* GR_SCALE_DYNAMIC */
201
202         group.gr_mem = members;
203         return &group;
204 }