/*
 * __getpwent.c - This file is part of the libc-8086/pwd package for ELKS,
 * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
 * 
 *  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; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "busybox.h" 

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include "pwd_.h"

#define PWD_BUFFER_SIZE 256

/* This isn't as flash as my previous version -- it doesn't dynamically
  scale down the gecos on too-long lines, but it also makes fewer syscalls,
  so it's probably nicer.  Write me if you want the old version.  Maybe I
  should include it as a build-time option... ?
  -Nat <ndf@linux.mit.edu> */

struct passwd *__getpwent(int pwd_fd)
{
	static char line_buff[PWD_BUFFER_SIZE];
	static struct passwd passwd;
	char *field_begin;
	char *endptr;
	char *gid_ptr=NULL;
	char *uid_ptr=NULL;
	int line_len;
	int i;

	/* We use the restart label to handle malformatted lines */
  restart:
	/* Read the passwd line into the static buffer using a minimal of
	   syscalls. */
	if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0)
		return NULL;
	field_begin = strchr(line_buff, '\n');
	if (field_begin != NULL)
		lseek(pwd_fd, (long) (1 + field_begin - (line_buff + line_len)),
			  SEEK_CUR);
	else {						/* The line is too long - skip it. :-\ */

		do {
			if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0)
				return NULL;
		} while (!(field_begin = strchr(line_buff, '\n')));
		lseek(pwd_fd, (long) (field_begin - line_buff) - line_len + 1,
			  SEEK_CUR);
		goto restart;
	}
	if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' ||
		*line_buff == '\t')
		goto restart;
	*field_begin = '\0';

	/* We've read the line; now parse it. */
	field_begin = line_buff;
	for (i = 0; i < 7; i++) {
		switch (i) {
		case 0:
			passwd.pw_name = field_begin;
			break;
		case 1:
			passwd.pw_passwd = field_begin;
			break;
		case 2:
			uid_ptr = field_begin;
			break;
		case 3:
			gid_ptr = field_begin;
			break;
		case 4:
			passwd.pw_gecos = field_begin;
			break;
		case 5:
			passwd.pw_dir = field_begin;
			break;
		case 6:
			passwd.pw_shell = field_begin;
			break;
		}
		if (i < 6) {
			field_begin = strchr(field_begin, ':');
			if (field_begin == NULL)
				goto restart;
			*field_begin++ = '\0';
		}
	}
	passwd.pw_gid = (gid_t) strtoul(gid_ptr, &endptr, 10);
	if (*endptr != '\0')
		goto restart;

	passwd.pw_uid = (uid_t) strtoul(uid_ptr, &endptr, 10);
	if (*endptr != '\0')
		goto restart;

	return &passwd;
}
