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 <unistd.h> 22#include <stdlib.h> 23#include <string.h> 24#include "grp.h" 25#include "config.h" 26 27/* 28 * This is the core group-file read function. It behaves exactly like 29 * getgrent() except that it is passed a file descriptor. getgrent() 30 * is just a wrapper for this function. 31 */ 32struct group *__getgrent(int grp_fd) 33{ 34#ifndef GR_SCALE_DYNAMIC 35 static char line_buff[GR_MAX_LINE_LEN]; 36 static char *members[GR_MAX_MEMBERS]; 37#else 38 static char *line_buff = NULL; 39 static char **members = NULL; 40 short line_index; 41 short buff_size; 42#endif 43 static struct group group; 44 register char *ptr; 45 char *field_begin; 46 short member_num; 47 char *endptr; 48 int line_len; 49 50 51 /* We use the restart label to handle malformatted lines */ 52 restart: 53#ifdef GR_SCALE_DYNAMIC 54 line_index = 0; 55 buff_size = 256; 56#endif 57 58#ifndef GR_SCALE_DYNAMIC 59 /* Read the line into the static buffer */ 60 if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) 61 return NULL; 62 field_begin = strchr(line_buff, '\n'); 63 if (field_begin != NULL) 64 lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)), 65 SEEK_CUR); 66 else { /* The line is too long - skip it :-\ */ 67 68 do { 69 if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) 70 return NULL; 71 } while (!(field_begin = strchr(line_buff, '\n'))); 72 lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1), 73 SEEK_CUR); 74 goto restart; 75 } 76 if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || 77 *line_buff == '\t') 78 goto restart; 79 *field_begin = '\0'; 80 81#else /* !GR_SCALE_DYNAMIC */ 82 line_buff = realloc(line_buff, buff_size); 83 while (1) { 84 if ((line_len = read(grp_fd, line_buff + line_index, 85 buff_size - line_index)) <= 0) 86 return NULL; 87 field_begin = strchr(line_buff, '\n'); 88 if (field_begin != NULL) { 89 lseek(grp_fd, 90 (long) (1 + field_begin - 91 (line_len + line_index + line_buff)), SEEK_CUR); 92 *field_begin = '\0'; 93 if (*line_buff == '#' || *line_buff == ' ' 94 || *line_buff == '\n' || *line_buff == '\t') 95 goto restart; 96 break; 97 } else { /* Allocate some more space */ 98 99 line_index = buff_size; 100 buff_size += 256; 101 line_buff = realloc(line_buff, buff_size); 102 } 103 } 104#endif /* GR_SCALE_DYNAMIC */ 105 106 /* Now parse the line */ 107 group.gr_name = line_buff; 108 ptr = strchr(line_buff, ':'); 109 if (ptr == NULL) 110 goto restart; 111 *ptr++ = '\0'; 112 113 group.gr_passwd = ptr; 114 ptr = strchr(ptr, ':'); 115 if (ptr == NULL) 116 goto restart; 117 *ptr++ = '\0'; 118 119 field_begin = ptr; 120 ptr = strchr(ptr, ':'); 121 if (ptr == NULL) 122 goto restart; 123 *ptr++ = '\0'; 124 125 group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10); 126 if (*endptr != '\0') 127 goto restart; 128 129 member_num = 0; 130 field_begin = ptr; 131 132#ifndef GR_SCALE_DYNAMIC 133 while ((ptr = strchr(ptr, ',')) != NULL) { 134 *ptr = '\0'; 135 ptr++; 136 members[member_num] = field_begin; 137 field_begin = ptr; 138 member_num++; 139 } 140 if (*field_begin == '\0') 141 members[member_num] = NULL; 142 else { 143 members[member_num] = field_begin; 144 members[member_num + 1] = NULL; 145 } 146#else /* !GR_SCALE_DYNAMIC */ 147 if (members != NULL) 148 free(members); 149 members = (char **) malloc(1 * sizeof(char *)); 150 151 while ((ptr = strchr(ptr, ',')) != NULL) { 152 *ptr = '\0'; 153 ptr++; 154 members[member_num] = field_begin; 155 field_begin = ptr; 156 member_num++; 157 members = 158 (char **) realloc((void *) members, 159 160 (member_num + 1) * sizeof(char *)); 161 } 162 if (*field_begin == '\0') 163 members[member_num] = NULL; 164 else { 165 members[member_num] = field_begin; 166 members[member_num + 1] = NULL; 167 } 168#endif /* GR_SCALE_DYNAMIC */ 169 170 group.gr_mem = members; 171 return &group; 172} 173