--- sash-3.4/__getgrent.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/__getgrent.c 2004-03-26 17:34:45.000000000 +0100 @@ -0,0 +1,202 @@ +/* + * __getgrent.c - This file is part of the libc-8086/grp 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 <unistd.h> +#include <stdlib.h> +#include <string.h> + +#include "grp_.h" + +/* + * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer + * so that lines of any length can be used. On very very small systems, + * you may want to leave this undefined becasue it will make the grp functions + * somewhat larger (because of the inclusion of malloc and the code necessary). + * On larger systems, you will want to define this, because grp will _not_ + * deal with long lines gracefully (they will be skipped). + */ +#undef GR_SCALE_DYNAMIC + +#ifndef GR_SCALE_DYNAMIC +/* + * If scaling is not dynamic, the buffers will be statically allocated, and + * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of + * characters per line in the group file. GR_MAX_MEMBERS is the maximum + * number of members of any given group. + */ +#define GR_MAX_LINE_LEN 128 +/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ +#define GR_MAX_MEMBERS 11 + +#endif /* !GR_SCALE_DYNAMIC */ + + +/* + * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate + * space for it's GID array before calling setgroups(). This is probably + * unnecessary scalage, so it's undefined by default. + */ +#undef GR_DYNAMIC_GROUP_LIST + +#ifndef GR_DYNAMIC_GROUP_LIST +/* + * GR_MAX_GROUPS is the size of the static array initgroups() uses for + * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. + */ +#define GR_MAX_GROUPS 64 + +#endif /* !GR_DYNAMIC_GROUP_LIST */ + + +/* + * This is the core group-file read function. It behaves exactly like + * getgrent() except that it is passed a file descriptor. getgrent() + * is just a wrapper for this function. + */ +struct group *bb_getgrent(int grp_fd) +{ +#ifndef GR_SCALE_DYNAMIC + static char line_buff[GR_MAX_LINE_LEN]; + static char *members[GR_MAX_MEMBERS]; +#else + static char *line_buff = NULL; + static char **members = NULL; + short line_index; + short buff_size; +#endif + static struct group group; + register char *ptr; + char *field_begin; + short member_num; + char *endptr; + int line_len; + + + /* We use the restart label to handle malformatted lines */ + restart: +#ifdef GR_SCALE_DYNAMIC + line_index = 0; + buff_size = 256; +#endif + +#ifndef GR_SCALE_DYNAMIC + /* Read the line into the static buffer */ + if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) + return NULL; + field_begin = strchr(line_buff, '\n'); + if (field_begin != NULL) + lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)), + SEEK_CUR); + else { /* The line is too long - skip it :-\ */ + + do { + if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) + return NULL; + } while (!(field_begin = strchr(line_buff, '\n'))); + lseek(grp_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'; + +#else /* !GR_SCALE_DYNAMIC */ + line_buff = realloc(line_buff, buff_size); + while (1) { + if ((line_len = read(grp_fd, line_buff + line_index, + buff_size - line_index)) <= 0) + return NULL; + field_begin = strchr(line_buff, '\n'); + if (field_begin != NULL) { + lseek(grp_fd, + (long) (1 + field_begin - + (line_len + line_index + line_buff)), SEEK_CUR); + *field_begin = '\0'; + if (*line_buff == '#' || *line_buff == ' ' + || *line_buff == '\n' || *line_buff == '\t') + goto restart; + break; + } else { /* Allocate some more space */ + + line_index = buff_size; + buff_size += 256; + line_buff = realloc(line_buff, buff_size); + } + } +#endif /* GR_SCALE_DYNAMIC */ + + /* Now parse the line */ + group.gr_name = line_buff; + ptr = strchr(line_buff, ':'); + if (ptr == NULL) + goto restart; + *ptr++ = '\0'; + + group.gr_passwd = ptr; + ptr = strchr(ptr, ':'); + if (ptr == NULL) + goto restart; + *ptr++ = '\0'; + + field_begin = ptr; + ptr = strchr(ptr, ':'); + if (ptr == NULL) + goto restart; + *ptr++ = '\0'; + + group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10); + if (*endptr != '\0') + goto restart; + + member_num = 0; + field_begin = ptr; + +#ifndef GR_SCALE_DYNAMIC + while ((ptr = strchr(ptr, ',')) != NULL) { + *ptr = '\0'; + ptr++; + members[member_num] = field_begin; + field_begin = ptr; + member_num++; + } + if (*field_begin == '\0') + members[member_num] = NULL; + else { + members[member_num] = field_begin; + members[member_num + 1] = NULL; + } +#else /* !GR_SCALE_DYNAMIC */ + free(members); + members = (char **) malloc((member_num + 1) * sizeof(char *)); + for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) { + if ((ptr = strchr(field_begin, ',')) != NULL) + *ptr++ = '\0'; + members[member_num++] = field_begin; + members = (char **) realloc(members, + (member_num + 1) * sizeof(char *)); + } + members[member_num] = NULL; +#endif /* GR_SCALE_DYNAMIC */ + + group.gr_mem = members; + return &group; +} --- sash-3.4/__getpwent.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/__getpwent.c 2004-03-26 16:59:55.000000000 +0100 @@ -0,0 +1,114 @@ +/* + * __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 <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; +} --- sash-3.4/getgrgid.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/getgrgid.c 2004-03-26 17:35:45.000000000 +0100 @@ -0,0 +1,42 @@ +/* + * getgrgid.c - This file is part of the libc-8086/grp 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 <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include "grp_.h" + +struct group *getgrgid(const gid_t gid) +{ + struct group *group; + int grp_fd; + + if ((grp_fd = open("/etc/group", O_RDONLY)) < 0) + return NULL; + + while ((group = bb_getgrent(grp_fd)) != NULL) + if (group->gr_gid == gid) { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} --- sash-3.4/getgrnam.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/getgrnam.c 2004-03-26 17:35:36.000000000 +0100 @@ -0,0 +1,48 @@ +/* + * getgrnam.c - This file is part of the libc-8086/grp 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 <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include "grp_.h" + +struct group *getgrnam(const char *name) +{ + int grp_fd; + struct group *group; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + if ((grp_fd = open("/etc/group", O_RDONLY)) < 0) + return NULL; + + while ((group = bb_getgrent(grp_fd)) != NULL) + if (!strcmp(group->gr_name, name)) { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} --- sash-3.4/getpwnam.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/getpwnam.c 2004-03-26 16:59:55.000000000 +0100 @@ -0,0 +1,49 @@ +/* + * getpwnam.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 <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include "pwd_.h" + + +struct passwd *getpwnam(const char *name) +{ + int passwd_fd; + struct passwd *passwd; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0) + return NULL; + + while ((passwd = __getpwent(passwd_fd)) != NULL) + if (!strcmp(passwd->pw_name, name)) { + close(passwd_fd); + return passwd; + } + + close(passwd_fd); + return NULL; +} --- sash-3.4/getpwuid.c.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/getpwuid.c 2004-03-26 16:59:55.000000000 +0100 @@ -0,0 +1,43 @@ +/* + * getpwuid.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 <stdlib.h> +#include <unistd.h> +#include <fcntl.h> + +#include "pwd_.h" + +struct passwd *getpwuid(uid_t uid) +{ + int passwd_fd; + struct passwd *passwd; + + if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0) + return NULL; + + while ((passwd = __getpwent(passwd_fd)) != NULL) + if (passwd->pw_uid == uid) { + close(passwd_fd); + return passwd; + } + + close(passwd_fd); + return NULL; +} --- sash-3.4/grp_.h.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/grp_.h 2004-03-26 17:34:14.000000000 +0100 @@ -0,0 +1,33 @@ +#ifndef __CONFIG_GRP_H +#define __CONFIG_GRP_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + + +/* The group structure */ +struct group +{ + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + gid_t gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ +}; + +extern void setgrent __P ((void)); +extern void endgrent __P ((void)); +extern struct group * getgrent __P ((void)); + +extern struct group * getgrgid __P ((__const gid_t gid)); +extern struct group * getgrnam __P ((__const char * name)); + +extern struct group * fgetgrent __P ((FILE * file)); + +extern int setgroups __P ((size_t n, __const gid_t * groups)); +extern int initgroups __P ((__const char * user, gid_t gid)); + +extern struct group * bb_getgrent __P ((int grp_fd)); + +#endif /* __CONFIG_GRP_H */ + --- sash-3.4/pwd_.h.pwd 2004-03-26 16:59:55.000000000 +0100 +++ sash-3.4/pwd_.h 2004-03-26 17:36:19.000000000 +0100 @@ -0,0 +1,35 @@ +#ifndef __CONFIG_PWD_H +#define __CONFIG_PWD_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + +/* The passwd structure. */ +struct passwd +{ + char *pw_name; /* Username. */ + char *pw_passwd; /* Password. */ + uid_t pw_uid; /* User ID. */ + gid_t pw_gid; /* Group ID. */ + char *pw_gecos; /* Real name. */ + char *pw_dir; /* Home directory. */ + char *pw_shell; /* Shell program. */ +}; + +extern void setpwent __P ((void)); +extern void endpwent __P ((void)); +extern struct passwd * getpwent __P ((void)); + +extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); +extern int getpw __P ((uid_t uid, char *buf)); + +extern struct passwd * fgetpwent __P ((FILE * file)); + +extern struct passwd * getpwuid __P ((__const uid_t)); +extern struct passwd * getpwnam __P ((__const char *)); + +extern struct passwd * __getpwent __P ((__const int passwd_fd)); + +#endif /* __CONFIG_PWD_H */ + --- sash-3.4/Makefile.pwd 2004-03-26 16:59:54.000000000 +0100 +++ sash-3.4/Makefile 2004-03-26 21:30:20.000000000 +0100 @@ -15,7 +15,9 @@ OBJS = sash.o cmds.o cmd_dd.o cmd_ed.o cmd_grep.o cmd_ls.o cmd_tar.o \ - cmd_gzip.o cmd_find.o cmd_file.o cmd_chattr.o cmd_ar.o utils.o + cmd_gzip.o cmd_find.o cmd_file.o cmd_chattr.o cmd_ar.o utils.o \ + getgrgid.o getgrnam.o getpwnam.o getpwuid.o __getgrent.o \ + __getpwent.o sash: $(OBJS)