* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / getent / __getpwent.c
blob9836ca7b54ff7c69985e41ed0955bf220fb97127
1 /*
2 * __getpwent.c - This file is part of the libc-8086/pwd 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.
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.
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.
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <pwd.h>
27 #define PWD_BUFFER_SIZE 256
29 /* This isn't as flash as my previous version -- it doesn't dynamically
30 scale down the gecos on too-long lines, but it also makes fewer syscalls,
31 so it's probably nicer. Write me if you want the old version. Maybe I
32 should include it as a build-time option... ?
33 -Nat <ndf@linux.mit.edu> */
35 struct passwd *
36 __getpwent(int pwd_fd)
38 static char line_buff[PWD_BUFFER_SIZE];
39 static struct passwd passwd;
40 char * field_begin;
41 char * endptr;
42 char * gid_ptr;
43 char * uid_ptr;
44 int line_len;
45 int i;
47 /* We use the restart label to handle malformatted lines */
48 restart:
49 /* Read the passwd line into the static buffer using a minimal of
50 syscalls. */
51 if ((line_len=read(pwd_fd, line_buff, PWD_BUFFER_SIZE))<=0)
52 return NULL;
53 field_begin=strchr(line_buff, '\n');
54 if (field_begin!=NULL)
55 lseek(pwd_fd, (long) (1+field_begin-(line_buff+line_len)), SEEK_CUR);
56 else /* The line is too long - skip it. :-\ */
58 do { if ((line_len=read(pwd_fd, line_buff, PWD_BUFFER_SIZE))<=0)
59 return NULL;
60 } while (!(field_begin=strchr(line_buff, '\n')));
61 lseek(pwd_fd, (long) (field_begin-line_buff)-line_len+1, SEEK_CUR);
62 goto restart;
64 if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' ||
65 *line_buff=='\t')
66 goto restart;
67 *field_begin='\0';
69 /* We've read the line; now parse it. */
70 field_begin=line_buff;
71 for (i=0;i<7;i++)
73 switch(i)
75 case 0: passwd.pw_name=field_begin; break;
76 case 1: passwd.pw_passwd=field_begin; break;
77 case 2: uid_ptr=field_begin; break;
78 case 3: gid_ptr=field_begin; break;
79 case 4: passwd.pw_gecos=field_begin; break;
80 case 5: passwd.pw_dir=field_begin; break;
81 case 6: passwd.pw_shell=field_begin; break;
83 if (i<6)
85 field_begin=strchr(field_begin, ':');
86 if (field_begin==NULL) goto restart;
87 *field_begin++='\0';
90 passwd.pw_gid=(gid_t) strtoul(gid_ptr, &endptr, 10);
91 if (*endptr!='\0') goto restart;
93 passwd.pw_uid=(uid_t) strtoul(uid_ptr, &endptr, 10);
94 if (*endptr!='\0') goto restart;
96 return &passwd;