/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
330, Boston, MA 02111-1307, USA. */
/* This code was borrowed from proftpd for muddleftpd :-P */
#include "../ftpd.h"
#define NPWDFIELDS 7
#define NGRPFIELDS 4
#ifndef BUFSIZ
#define BUFSIZ 1024
#endif
/* provides fgetpwent()/fgetgrent() functions. Note that the
* format of the files is probably NOT platform dependant, so
* use of these functions will require a strict format
* "username:password:uid:gid:gecos:home:default_shell"
*/
#ifndef HAVE_FGETPWENT
static char pwdbuf[BUFSIZ];
static char *pwdfields[NPWDFIELDS];
static struct passwd pwent;
static struct passwd *_pgetpwent(const char *buf)
{
register int i;
register char *cp;
char *ep;
char **fields;
char *buffer;
struct passwd *pwd;
fields = pwdfields;
buffer = pwdbuf;
pwd = &pwent;
strncpy(buffer,buf,BUFSIZ-1);
buffer[BUFSIZ-1] = '\0';
for(cp = buffer, i = 0; i < NPWDFIELDS && cp; i++) {
fields[i] = cp;
while(*cp && *cp != ':')
++cp;
if(*cp)
*cp++ = '\0';
else
cp = 0;
}
if(i != NPWDFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
return 0;
pwd->pw_name = fields[0];
pwd->pw_passwd = fields[1];
if(fields[2][0] == '\0' ||
((pwd->pw_uid = strtol(fields[2], &ep, 10)) == 0 && *ep))
return 0;
if(fields[3][0] == '\0' ||
((pwd->pw_gid = strtol(fields[3], &ep, 10)) == 0 && *ep))
return 0;
pwd->pw_gecos = fields[4];
pwd->pw_dir = fields[5];
pwd->pw_shell = fields[6];
return pwd;
}
struct passwd *fgetpwent(FILE *fp)
{
char buf[BUFSIZ];
if (fgets(buf,sizeof(buf),fp) != (char*)0)
{
buf[strlen(buf)-1] = '\0';
return _pgetpwent(buf);
}
return NULL;
}
#endif /* HAVE_FGETPWENT */
#ifndef HAVE_FGETGRENT
#define MAXMEMBERS 4096
static char *grpbuf = NULL;
static struct group grent;
static char *grpfields[NGRPFIELDS];
static char *members[MAXMEMBERS+1];
static char *fgetbufline(char **buf, int *size, FILE *fp)
{
char *rbuf = NULL,*cp;
if(!*size || !*buf) {
*size = BUFSIZ;
*buf = rbuf = malloc(*size);
if(!rbuf)
return 0;
}
cp = rbuf;
while(fgets(cp,(*size) - (cp - rbuf), fp) != (char *)0) {
if(strchr(cp,'\n'))
return rbuf;
*size += *size;
*buf = realloc(rbuf,*size);
if(!*buf)
break;
cp = *buf + (cp - rbuf);
rbuf = *buf;
cp = strchr(cp,'\0');
}
free(rbuf);
*buf = NULL; *size = 0;
return 0;
}
static char **_grlist(char *s)
{
int nmembers = 0;
while(s && *s && nmembers < MAXMEMBERS) {
members[nmembers++] = s;
while(*s && *s != ',')
s++;
if(*s)
*s++ = '\0';
}
members[nmembers] = (char*)0;
return members;
}
static struct group *
_pgetgrent(const char *buf)
{
int i;
char *cp;
i = strlen(buf);
if(!grpbuf)
grpbuf = malloc(i);
else
grpbuf = realloc(grpbuf,i);
if(!grpbuf)
return NULL;
strncpy(grpbuf,buf,i);
grpbuf[i-1] = '\0';
if((cp = strrchr(grpbuf,'\n')))
*cp = '\0';
for(cp = grpbuf, i = 0; i < NGRPFIELDS && cp; i++) {
grpfields[i] = cp;
if((cp = strchr(cp,':')))
*cp++ = 0;
}
if(i < (NGRPFIELDS-1) || *grpfields[2] == '\0')
return 0;
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
grent.gr_gid = atoi(grpfields[2]);
grent.gr_mem = _grlist(grpfields[3]);
return &grent;
}
struct group *fgetgrent(FILE *fp)
{
char *buf = NULL;
int size = 0;
char *cp;
struct group *g;
if(fgetbufline(&buf,&size,fp) != (char*)0) {
if((cp = strchr(buf,'\n')) != (char*)0)
*cp = '\0';
g = _pgetgrent(buf);
free(buf);
return g;
}
return 0;
}
#endif /* HAVE_FGETGRENT */
syntax highlighted by Code2HTML, v. 0.9.1