Initial revision
[kopensolaris-gnu/glibc.git] / grp / grpread.c
1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <ansidecl.h>
20 #include <errno.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <grp.h>
26
27 /* This is the function that all the others are based on.
28    The format of the group file is known only here.  */
29
30 /* Structure containing info kept by each __grpread caller.  */
31 typedef struct
32   {
33 #define NAME_SIZE       9
34 #define PASSWD_SIZE     21
35 #define MEMLIST_SIZE    1001
36     char name[NAME_SIZE], passwd[PASSWD_SIZE], memlist[MEMLIST_SIZE];
37     size_t max_members;
38     char **members;
39     struct group g;
40   } grpread_info;
41
42
43 /* Return a chunk of memory containing a pre-initialized `grpread_info'.  */
44 PTR
45 DEFUN_VOID(__grpalloc)
46 {
47   grpread_info *info = (PTR) malloc(sizeof(grpread_info));
48   if (info == NULL)
49     return NULL;
50
51   info->max_members = 5;
52   info->members = (char **) malloc(5 * sizeof(char *));
53   if (info->members == NULL)
54     {
55       free((PTR) info);
56       return NULL;
57     }
58
59   return info;
60 }
61
62 /* Read a group entry from STREAM, filling in G.  */
63 struct group *
64 DEFUN(__grpread, (stream, g), FILE *stream AND PTR CONST g)
65 {
66   register grpread_info *CONST info = (grpread_info *) g;
67   register size_t i;
68   register char *s;
69
70   /* Idiocy checks.  */
71   if (stream == NULL)
72     {
73       errno = EINVAL;
74       return NULL;
75     }
76
77   if (fscanf(stream, "%8[^:]:%20[^:]:%hd:%1000[^\n]\n",
78              info->name, info->passwd, &info->g.gr_gid, info->memlist) != 4)
79     return NULL;
80
81   /* Turn the comma-separated list into an array.  */
82   i = 0;
83   for (s = strtok(info->memlist, ","); s != NULL;
84        s = strtok((char *) NULL, ","))
85     {
86       if (i == info->max_members - 2)
87         {
88           info->max_members += 5;
89           info->members = (char **)
90             realloc((PTR) info->members, info->max_members * sizeof(char *));
91           if (info->members == NULL)
92             return NULL;
93         }
94
95       info->members[i++] = s;
96     }
97   info->members[i] = NULL;
98
99   info->g.gr_name = info->name;
100   info->g.gr_passwd = info->passwd;
101   info->g.gr_mem = info->members;
102   return &info->g;
103 }