home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C "$Id: getgroupent.c,v 1.3 1993/10/15 01:16:22 ppessi Exp $";
- /*
- * getgroupent.c - getgrp*() for network library
- *
- * This file is part of the AmiTCP/IP Network Library.
- *
- * Author: ppessi <Pekka.Pessi@hut.fi>
- * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-Group@hut.fi>
- * Helsinki University of Technology, Finland.
- *
- * Created : Sun Jun 20 17:52:37 1993 ppessi
- * Last modified: Thu Oct 14 19:25:25 1993 ppessi
- */
-
- #include <exec/memory.h>
- #include <dos/dos.h>
-
- #include <string.h>
- #include <sys/errno.h>
-
- #include "grp.h"
-
- #if !NETLIB
- #error
- #else
- #include <proto/dos.h>
-
- #include <errno.h>
- #define SetNetErr(x) (errno=(x))
- static BPTR grpfh = NULL;
-
- #define INTERNAL static
-
- #endif
-
- /*
- * Parsing function
- */
- extern int do_parse(UBYTE *str, int n, UBYTE **array);
-
- /* End reading group entities */
- INTERNAL void EndGroupEnt(void)
- {
- if (grpfh) Close(grpfh), grpfh = NULL;
- }
-
- /* Restart reading group entities */
- INTERNAL void SetGroupEnt(void)
- {
- if (grpfh) EndGroupEnt();
-
- grpfh = Open(_PATH_GROUP, MODE_OLDFILE);
- #if TESTING
- atexit(EndGroupEnt);
- #endif
- }
-
- /* Read the next entry from the group-file database */
- INTERNAL struct group *GetGroupEnt(struct group *g, ULONG size)
- {
- UBYTE *p, *buffer = (UBYTE*)g;
- UBYTE **members;
- ULONG s;
- int err = 0;
-
- if (size - sizeof(struct group) < 0) {
- err = ENOBUFS;
- goto bad;
- }
-
- memset(buffer, sizeof(struct group), 0);
-
- size -= sizeof(struct group) + 1;
- buffer += sizeof(struct group);
- /* fix a bug in the FGetS routine */
- buffer[size] = '\0';
-
- if (!grpfh)
- SetGroupEnt();
-
- if (!grpfh || !FGets(grpfh, buffer, size)) {
- err = ENOENT;
- goto bad;
- }
-
- /* Make space for the member list */
- for (s = 2, p = buffer; *p; p++) {
- if (*p == ',')
- s++;
- }
- if (*--p != '\n' || p - buffer + s * sizeof(*members) > size) {
- /* Too long! */
- err = ENOBUFS;
- goto bad;
- }
-
- {
- UBYTE *from = p + 1, *to = p + s * sizeof(*members) + 1;
- while (from >= buffer) {
- *to-- = *from--;
- }
- buffer = to + 1;
- }
-
- if (err = do_parse(buffer, 4, (UBYTE **)g))
- goto bad;
-
- /* Parse the group ID field */
- if (StrToLong((UBYTE*)g->gr_gid, &g->gr_gid) <= 0)
- if ((s = StrToLong(p, &g->gr_gid)) <= 0 || p[s] != '|') {
- err = EFTYPE;
- goto bad;
- }
-
- /* Parse the memberlist */
- p = (UBYTE*)g->gr_mem;
- for (g->gr_mem = members = (UBYTE **)(g + 1); *p;) {
- *members++ = p;
- while (*p && *p++ != ',')
- ;
- }
- *members = NULL;
-
- return g;
-
- bad:
- SetNetErr(err);
- EndGroupEnt();
- return (struct group*) NULL;
- }
-
- /* Search for an entry with a matching group ID */
- INTERNAL struct group *GetGroupGID(ULONG gid,
- struct group *g,
- ULONG size)
- {
- while ((g = GetGroupEnt(g, size)) && (g->gr_gid != gid))
- ;
- EndGroupEnt();
- return g;
- }
-
- /* Search for an entry with a matching group name */
- INTERNAL struct group *GetGroupName(const UBYTE *name,
- struct group *g,
- ULONG size)
- {
- while ((g = GetGroupEnt(g, size)) && strcmp(g->gr_name, name))
- ;
- EndGroupEnt();
- return g;
- }
-
- /*
- * A global structure for Unix compatible functions
- */
- #define GSTORE_SIZE 1024
- static struct group * gstore = NULL;
-
- #include <stdlib.h>
-
- static struct group * alloc_gstore(void)
- {
- return gstore = (struct group *)malloc(GSTORE_SIZE);
- }
-
- /*
- * POSIX compatible getgrgid()
- */
- struct group *getgrgid(gid_t gid)
- {
- if (!gstore && !alloc_gstore()) {
- return NULL;
- }
-
- return GetGroupGID((ULONG) gid, gstore, GSTORE_SIZE);
- }
-
- /*
- * POSIX compatible getgrnam
- */
- struct group *getgrnam(const char *name)
- {
- if (!gstore && !alloc_gstore()) {
- return NULL;
- }
-
- return GetGroupName((UBYTE *) name, gstore, GSTORE_SIZE);
- }
-
-