text:
package ohirakyou.turtletech.common.crafting;

import cyano.basemetals.material.MetalMaterial;
import cyano.basemetals.registry.CrusherRecipeRegistry;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe;
import ohirakyou.turtletech.common.material.Materials;
import ohirakyou.turtletech.common.block.ModBlocks;
import ohirakyou.turtletech.common.item.ModItems;
import ohirakyou.turtletech.data.DataMods;
import org.apache.commons.lang3.ArrayUtils;

//// TODO: 6/14/2016  Automate creation of recipe enable/disable toggles in config

public final class ModCrafting {

    private static boolean initDone = false;
    public static void init() {
        if(initDone)return;

        initMetalRecipes();
        initCustomRecipes();

        initDone = true;
    }

    private static void initCustomRecipes() {
        // Miscellaneous cast iron items
        addHollowCubeRecipe(ModBlocks.cast_iron_casing, ModBlocks.cast_iron_plate, "plateCastIron");

        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.cast_iron_tread, 2),
                " i ",
                "ibi",
                'i', ModItems.cast_iron_ingot, 'b', ModBlocks.cast_iron_block));

        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.cast_iron_grate, 6),
                "i i",
                " i ",
                "i i",
                'i', "ingotCastIron"));

        // Stairs
        addStairsRecipe(ModBlocks.cast_iron_stairs, ModBlocks.cast_iron_block);
        addStairsRecipe(ModBlocks.cast_iron_casing_stairs, ModBlocks.cast_iron_casing);

        // Slabs
        addSlabRecipe(ModBlocks.cast_iron_slab, ModBlocks.cast_iron_block);

        // Generators
        addCastIronGeneratorRecipe(ModBlocks.redstone_reflex_generator, Blocks.PISTON);
        addCastIronGeneratorRecipe(ModBlocks.solar_reflex_generator, Blocks.PISTON, Blocks.DAYLIGHT_DETECTOR);

        addCastIronGeneratorRecipe(ModBlocks.soul_turbine_generator, "ingotSoularium");
        if (!(Loader.isModLoaded(DataMods.ENDERIO))) {
            addCastIronGeneratorRecipe(ModBlocks.soul_turbine_generator, "ingotGold", Blocks.SOUL_SAND, "ingotGold");
        }

        // Turrets
        addCastIronMachineRecipe(ModBlocks.precision_laser_turret, "pde", new Object[]{
                'p', "PSU", 'd', "gemDiamond", 'e', "gemEmerald"});
        addCastIronMachineRecipe(ModBlocks.precision_laser_turret, "ped", new Object[]{
                'p', "PSU", 'd', "gemDiamond", 'e', "gemEmerald"});

        if (!(Loader.isModLoaded(DataMods.ELECTRIC_ADVANTAGE))) {
            // Fallback for when Electric Advantage is not installed
            addCastIronMachineRecipe(ModBlocks.precision_laser_turret, "ede", new Object[]{
                    'd', "gemDiamond", 'e', "gemEmerald"});
        }

        addCastIronMachineRecipe(ModBlocks.turret_extender,
                " p ",
                " i ",
                new Object[]{'p', "plateCastIron", 'i', Blocks.PISTON});

        // Machines
        GameRegistry.addRecipe(new ShapedOreRecipe(ModBlocks.foundry,
                "coc",
                "bcb",
                "bbb",
                'c', Items.CLAY_BALL, 'o', new ItemStack(Items.COAL, 1, OreDictionary.WILDCARD_VALUE), 'b', "ingotBrick"));
    }

    private static void addSlabRecipe(Block slab, Block block) {
        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(slab, 4),
                "bb",
                'b', block));

        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(block, 1),
                "s",
                "s",
                's', slab));
    }

    private static void addStairsRecipe(Block stairs, Block block) {
        // Blocks -> stairs
        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(stairs, 8),
                "b  ",
                "bb ",
                "bbb",
                'b', block));
        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(stairs, 8),
                "  b",
                " bb",
                "bbb",
                'b', block));

        // Stairs -> blocks
        GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(block, 3),
                "ss",
                "ss",
                's', stairs));
    }

    private static void addHollowCubeRecipe(Block cube, Block plate, String plateName) {
        // Plates -> cube
        GameRegistry.addRecipe(new ShapelessOreRecipe(cube,
                plateName, plateName, plateName, plateName, plateName, plateName));

        // Cube -> plates
        GameRegistry.addShapelessRecipe(new ItemStack(plate, 6), cube);
    }

    private static void addCastIronGeneratorRecipe(Block generator, Object driver) {
        addCastIronGeneratorRecipe(generator, " d ", new Object[]{'d', driver});

        //todo create a simple base generator and add a recipe that uses it and the driver
        //GameRegistry.addRecipe(new ShapelessOreRecipe(generator, driver, ModBlocks.simple_generator));
    }

    private static void addCastIronGeneratorRecipe(Block generator, Object driver1, Object driver2) {
        Object[] materials = new Object[]{'a', driver1, 'b', driver2};
        addCastIronGeneratorRecipe(generator, "ba ", materials);
        addCastIronGeneratorRecipe(generator, " ab", materials);
    }

    private static void addCastIronGeneratorRecipe(Block generator, Object driver1, Object driver2, Object driver3) {
        Object[] materials = new Object[]{'a', driver1, 'b', driver2, 'c', driver3};
        addCastIronGeneratorRecipe(generator, "abc", materials);
    }

    private static void addCastIronGeneratorRecipe(Block generator, String topRow, Object[] driverMaterials) {
        // Capital letters are used here to distinguish shared generator materials from unique driver materials
        Object[] generatorMaterials = {'O', "ingotCopper", 'I', "ingotIron",};
        Object[] materials = ArrayUtils.addAll(driverMaterials, generatorMaterials);

        addCastIronMachineRecipe(generator, topRow, "OIO", materials);
    }

    private static void addCastIronMachineRecipe(Block machine, String topRow, Object[] machineMaterials) {
        addCastIronMachineRecipe(machine, new Object[]{topRow}, machineMaterials);
    }

    private static void addCastIronMachineRecipe(Block machine, String topRow, String middleRow, Object[] machineMaterials) {
        addCastIronMachineRecipe(machine, new Object[]{topRow, middleRow}, machineMaterials);
    }

    private static void addCastIronMachineRecipe(Block machine, Object[] rows, Object[] machineMaterials) {
        // Capital letters are used here to distinguish shared machine materials from unique recipe materials
        Object[] shapeDefinition = ArrayUtils.add(rows, "RCR");

        Object[] generatorMaterials = {'R', "dustRedstone", 'C', ModBlocks.cast_iron_casing};

        Object[] finalRecipe = ArrayUtils.addAll(shapeDefinition, machineMaterials);
        finalRecipe = ArrayUtils.addAll(finalRecipe, generatorMaterials);

        GameRegistry.addRecipe(new ShapedOreRecipe(machine, finalRecipe));
    }

    private static void initMetalRecipes(){
        MetalMaterial metal = Materials.cast_iron;

        String baseName = metal.getName()+"_";
        String oreDictName = metal.getCapitalizedName();

        Item axe = ModItems.getItemByName(baseName+"axe");
        Item blend = ModItems.getItemByName(baseName+"blend");
        Item boots = ModItems.getItemByName(baseName+"boots");
        Item chestplate = ModItems.getItemByName(baseName+"chestplate");
        Item crackhammer = ModItems.getItemByName(baseName+"crackhammer");
        Item door = ModItems.getItemByName(baseName+"door_item");
        Item helmet = ModItems.getItemByName(baseName+"helmet");
        Item hoe = ModItems.getItemByName(baseName+"hoe");
        Item ingot = ModItems.getItemByName(baseName+"ingot");
        Item leggings = ModItems.getItemByName(baseName+"leggings");
        Item nugget = ModItems.getItemByName(baseName+"nugget");
        Item pickaxe = ModItems.getItemByName(baseName+"pickaxe");
        Item powder = ModItems.getItemByName(baseName+"powder");
        Item shovel = ModItems.getItemByName(baseName+"shovel");
        Item sword = ModItems.getItemByName(baseName+"sword");
        Item rod = ModItems.getItemByName(baseName+"rod");
        Item gear = ModItems.getItemByName(baseName+"gear");
        Block bars = ModBlocks.getBlockByName(baseName+"bars");
        Block block = ModBlocks.getBlockByName(baseName+"block");
        Block plate = ModBlocks.getBlockByName(baseName+"plate");
        Block ore = ModBlocks.getBlockByName(baseName+"ore");
        Block trapdoor = ModBlocks.getBlockByName(baseName+"trapdoor");

        Item arrow = ModItems.getItemByName(baseName+"arrow");
        Item bow = ModItems.getItemByName(baseName+"bow");
        Item bolt = ModItems.getItemByName(baseName+"bolt");
        Item crossbow = ModItems.getItemByName(baseName+"crossbow");
        Item shears = ModItems.getItemByName(baseName+"shears");
        Item smallblend = ModItems.getItemByName(baseName+"smallblend");
        Item smallpowder = ModItems.getItemByName(baseName+"smallpowder");
        Item fishingrod = ModItems.getItemByName(baseName+"fishingrod");

        // NOTE: smelting XP is based on output item, not input item
        // ingot-related recipes
        if(ore != null && powder != null){
            CrusherRecipeRegistry.addNewCrusherRecipe("ore"+oreDictName,new ItemStack(powder,2));
        }
        if(ore != null && ingot != null){
            GameRegistry.addSmelting(ore, new ItemStack(ingot,1), metal.getOreSmeltXP());
        }
        if(ingot != null && powder != null){
            CrusherRecipeRegistry.addNewCrusherRecipe("ingot"+oreDictName,new ItemStack(powder,1));
            GameRegistry.addSmelting(powder, new ItemStack(ingot,1), metal.getOreSmeltXP());
        }
        if(ingot != null && blend != null){
            GameRegistry.addSmelting(blend, new ItemStack(ingot,1), metal.getOreSmeltXP());
        }
        if(ingot != null && nugget != null){
            GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(nugget,9), new ItemStack(ingot)));
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ingot), "xxx","xxx","xxx",'x',"nugget"+oreDictName));
        }
        if(ingot != null && block != null){
            GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(ingot,9), new ItemStack(block)));
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(block), "xxx","xxx","xxx",'x',"ingot"+oreDictName));
        }
        if(ingot != null && plate != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(plate,3), "xxx",'x',"ingot"+oreDictName));
            GameRegistry.addSmelting(plate, new ItemStack(ingot,1), metal.getOreSmeltXP());
        }
        if(block != null && powder != null){
            CrusherRecipeRegistry.addNewCrusherRecipe("block"+oreDictName, new ItemStack(powder,9));
        }
        if(ingot != null && bars != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(bars,16), "xxx","xxx",'x',"ingot"+oreDictName));
            OreDictionary.registerOre("bars", bars);
        }
        if(ingot != null && rod != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(rod,4), "x","x",'x',"ingot"+oreDictName));
            OreDictionary.registerOre("stick"+oreDictName,rod);
            OreDictionary.registerOre("rod"+oreDictName,rod);
            OreDictionary.registerOre("rod",rod);
        }
        if(nugget != null && rod != null){
            GameRegistry.addSmelting(rod, new ItemStack(nugget,4), 0);
        }
        if(rod != null && bars != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(bars,4), "xxx",'x',"rod"+oreDictName));
        }
        if(rod != null && ingot != null && gear != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(gear,4), " x ","x/x"," x ",'x',"ingot"+oreDictName,'/',"rod"+oreDictName));
            OreDictionary.registerOre("gear"+oreDictName,gear);
            OreDictionary.registerOre("gear",gear);
        }
        if(ingot != null && door != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(door,3), "xx","xx","xx",'x',"ingot"+oreDictName));
            OreDictionary.registerOre("door", door);
        }
        if(ingot != null && trapdoor != null){
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(trapdoor), "xx","xx",'x',"ingot"+oreDictName));
            OreDictionary.registerOre("trapdoor", trapdoor);
        }

        if(blend != null && smallblend != null){
            GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(smallblend,9), new ItemStack(blend)));
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blend), "xxx","xxx","xxx",'x',new ItemStack(smallblend)));
            GameRegistry.addSmelting(smallblend, new ItemStack(nugget,1), metal.getOreSmeltXP());
        }
        if(powder != null && smallpowder != null){
            GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(smallpowder,9), new ItemStack(powder)));
            GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(powder), "xxx","xxx","xxx",'x',new ItemStack(smallpowder)));
            GameRegistry.addSmelting(smallpowder, new ItemStack(nugget,1), metal.getOreSmeltXP());
            CrusherRecipeRegistry.addNewCrusherRecipe("nugget"+oreDictName,new ItemStack(smallpowder,1));
        }

        // Armor and tools
        if(ingot != null && boots != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(boots), "x x", "x x", 'x', "ingot"+oreDictName));
        if(ingot != null && helmet != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(helmet), "xxx", "x x", 'x', "ingot"+oreDictName));
        if(ingot != null && chestplate != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(chestplate), "x x", "xxx", "xxx", 'x', "ingot"+oreDictName));
        if(ingot != null && leggings != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(leggings), "xxx", "x x", "x x", 'x', "ingot"+oreDictName));
        if(ingot != null && axe != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(axe), "xx", "x/", " /", 'x', "ingot"+oreDictName,'/', "stickWood"));
        if(block != null && crackhammer != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(crackhammer), "x", "/", "/" , 'x', "block"+oreDictName, '/', "stickWood"));
        if(ingot != null && hoe != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(hoe), "xx", " /" , " /", 'x', "ingot"+oreDictName, '/', "stickWood"));
        if(ingot != null && pickaxe != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(pickaxe), "xxx", " / ", " / ", 'x', "ingot"+oreDictName, '/', "stickWood"));
        if(ingot != null && shovel != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(shovel), "x", "/", "/", 'x', "ingot"+oreDictName, '/', "stickWood"));
        if(ingot != null && sword != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(sword), "x", "x" , "/", 'x', "ingot"+oreDictName, '/', "stickWood"));
        if(ingot != null && shears != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(shears), " x", "x " , 'x', "ingot"+oreDictName));

        // Bows and crossbows
        if(rod != null && arrow != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(arrow), "x", "y", "z", 'x', "nugget"+oreDictName, 'y', "rod"+oreDictName,'z' ,net.minecraft.init.Items.FEATHER));
        if(rod != null && bow != null) GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(bow), " xy", "x y", " xy", 'x', "rod"+oreDictName, 'y', net.minecraft.init.Items.STRING));

        // alloy blends
        GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(ModItems.cast_iron_blend, 2), "dustIron", "dustCarbon"));
        GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(ModItems.cast_iron_blend, 2), "dustIron", "dustCoal"));
    }

}


text:
/*	$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $	*/

/*-
 * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Luke Mewburn.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)getgrent.c	8.2 (Berkeley) 3/21/94";
#else
__RCSID("$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $");
#endif
#endif /* LIBC_SCCS and not lint */

#include "namespace.h"
#include "reentrant.h"

#include <sys/param.h>

#include <assert.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <nsswitch.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>

#ifdef HESIOD
#include <hesiod.h>
#endif

#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#endif

#include "gr_private.h"

#ifdef __weak_alias
__weak_alias(endgrent,_endgrent)
__weak_alias(getgrent,_getgrent)
__weak_alias(getgrent_r,_getgrent_r)
__weak_alias(getgrgid,_getgrgid)
__weak_alias(getgrgid_r,_getgrgid_r)
__weak_alias(getgrnam,_getgrnam)
__weak_alias(getgrnam_r,_getgrnam_r)
__weak_alias(setgrent,_setgrent)
__weak_alias(setgroupent,_setgroupent)
#endif

#ifdef _REENTRANT
mutex_t	__grmutex = MUTEX_INITIALIZER;
#endif

/*
 * _gr_memfrombuf
 *	Obtain want bytes from buffer (of size buflen) and return a pointer
 *	to the available memory after adjusting buffer/buflen.
 *	Returns NULL if there is insufficient space.
 */
static char *
_gr_memfrombuf(size_t want, char **buffer, size_t *buflen)
{
	char	*rv;

	if (want > *buflen) {
		errno = ERANGE;
		return NULL;
	}
	rv = *buffer;
	*buffer += want;
	*buflen -= want;
	return rv;
}

/*
 * _gr_parse
 *	Parses entry as a line per group(5) (without the trailing \n)
 *	and fills in grp with corresponding values; memory for strings
 *	and arrays will be allocated from buf (of size buflen).
 *	Returns 1 if parsed successfully, 0 on parse failure.
 */
static int
_gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen)
{
	unsigned long	id;
	const char	*bp;
	char		*ep;
	size_t		count;
	int		memc;

	_DIAGASSERT(entry != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buf != NULL);

#define COPYTOBUF(to) \
	do { \
		(to) = _gr_memfrombuf(count+1, &buf, &buflen); \
		if ((to) == NULL) \
			return 0; \
		memmove((to), entry, count); \
		to[count] = '\0'; \
	} while (0)	/* LINTED */

#if 0
	if (*entry == '+')			/* fail on compat `+' token */
		return 0;
#endif

	count = strcspn(entry, ":");		/* parse gr_name */
	if (entry[count] == '\0')
		return 0;
	COPYTOBUF(grp->gr_name);
	entry += count + 1;

	count = strcspn(entry, ":");		/* parse gr_passwd */
	if (entry[count] == '\0')
		return 0;
	COPYTOBUF(grp->gr_passwd);
	entry += count + 1;

	count = strcspn(entry, ":");		/* parse gr_gid */
	if (entry[count] == '\0')
		return 0;
	id = strtoul(entry, &ep, 10);
	if (id > GID_MAX || *ep != ':')
		return 0;
	grp->gr_gid = (gid_t)id;
	entry += count + 1;

	memc = 1;				/* for final NULL */
	if (*entry != '\0')
		memc++;				/* for first item */
	for (bp = entry; *bp != '\0'; bp++) {
		if (*bp == ',')
			memc++;
	}
				/* grab ALIGNed char **gr_mem from buf */
	ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
	if (ep == NULL)
		return 0;
	grp->gr_mem = (char **)ALIGN(ep);

	for (memc = 0; *entry != '\0'; memc++) {
		count = strcspn(entry, ",");	/* parse member */
		COPYTOBUF(grp->gr_mem[memc]);
		entry += count;
		if (*entry == ',')
			entry++;
	}

#undef COPYTOBUF

	grp->gr_mem[memc] = NULL;
	return 1;
}

/*
 * _gr_copy
 *	Copy the contents of fromgrp to grp; memory for strings
 *	and arrays will be allocated from buf (of size buflen).
 *	Returns 1 if copied successfully, 0 on copy failure.
 *	NOTE: fromgrp must not use buf for its own pointers.
 */
static int
_gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen)
{
	char	*ep;
	int	memc;

	_DIAGASSERT(fromgrp != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buf != NULL);

#define COPYSTR(to, from) \
	do { \
		size_t count = strlen((from)); \
		(to) = _gr_memfrombuf(count+1, &buf, &buflen); \
		if ((to) == NULL) \
			return 0; \
		memmove((to), (from), count); \
		to[count] = '\0'; \
	} while (0)	/* LINTED */

	COPYSTR(grp->gr_name, fromgrp->gr_name);
	COPYSTR(grp->gr_passwd, fromgrp->gr_passwd);
	grp->gr_gid = fromgrp->gr_gid;

	if (fromgrp->gr_mem == NULL)
		return 0;

	for (memc = 0; fromgrp->gr_mem[memc]; memc++)
		continue;
	memc++;					/* for final NULL */

				/* grab ALIGNed char **gr_mem from buf */
	ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
	grp->gr_mem = (char **)ALIGN(ep);
	if (grp->gr_mem == NULL)
		return 0;

	for (memc = 0; fromgrp->gr_mem[memc]; memc++) {
		COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]);
	}

#undef COPYSTR

	grp->gr_mem[memc] = NULL;
	return 1;
}

		/*
		 *	files methods
		 */

int
__grstart_files(struct __grstate_files *state)
{

	_DIAGASSERT(state != NULL);

	if (state->fp == NULL) {
		state->fp = fopen(_PATH_GROUP, "re");
		if (state->fp == NULL)
			return NS_UNAVAIL;
	} else {
		rewind(state->fp);
	}
	return NS_SUCCESS;
}

int
__grend_files(struct __grstate_files *state)
{

	_DIAGASSERT(state != NULL);

	if (state->fp) {
		(void) fclose(state->fp);
		state->fp = NULL;
	}
	return NS_SUCCESS;
}

/*
 * __grscan_files
 *	Scan state->fp for the next desired entry.
 *	If search is zero, return the next entry.
 *	If search is non-zero, look for a specific name (if name != NULL),
 *	or a specific gid (if name == NULL).
 *	Sets *retval to the errno if the result is not NS_SUCCESS
 *	or NS_NOTFOUND.
 */
int
__grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen,
	struct __grstate_files *state, int search, const char *name, gid_t gid)
{
	int	rv;
	char	filebuf[_GETGR_R_SIZE_MAX], *ep;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(state != NULL);
	/* name is NULL to indicate searching for gid */

	*retval = 0;

	if (state->fp == NULL) {	/* only start if file not open yet */
		rv = __grstart_files(state);
		if (rv != NS_SUCCESS)
			goto filesgrscan_out;
	}

	rv = NS_NOTFOUND;

							/* scan line by line */
	while (fgets(filebuf, (int)sizeof(filebuf), state->fp) != NULL) {
		ep = strchr(filebuf, '\n');
		if (ep == NULL) {	/* skip lines that are too big */
			int ch;

			while ((ch = getc(state->fp)) != '\n' && ch != EOF)
				continue;
			continue;
		}
		*ep = '\0';				/* clear trailing \n */

		if (filebuf[0] == '+')			/* skip compat line */
			continue;

							/* validate line */
		if (! _gr_parse(filebuf, grp, buffer, buflen)) {
			continue;			/* skip bad lines */
		}
		if (! search) {				/* just want this one */
			rv = NS_SUCCESS;
			break;
		}
							/* want specific */
		if ((name && strcmp(name, grp->gr_name) == 0) ||
		    (!name && gid == grp->gr_gid)) {
			rv = NS_SUCCESS;
			break;
		}
	}

 filesgrscan_out:
	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
		*retval = errno;
	return rv;
}

static struct __grstate_files	_files_state;
					/* storage for non _r functions */
static struct group		_files_group;
static char			_files_groupbuf[_GETGR_R_SIZE_MAX];

/*ARGSUSED*/
static int
_files_setgrent(void *nsrv, void *nscb, va_list ap)
{

	_files_state.stayopen = 0;
	return __grstart_files(&_files_state);
}

/*ARGSUSED*/
static int
_files_setgroupent(void *nsrv, void *nscb, va_list ap)
{
	int	*retval		= va_arg(ap, int *);
	int	 stayopen	= va_arg(ap, int);

	int	rv;

	_files_state.stayopen = stayopen;
	rv = __grstart_files(&_files_state);
	*retval = (rv == NS_SUCCESS);
	return rv;
}

/*ARGSUSED*/
static int
_files_endgrent(void *nsrv, void *nscb, va_list ap)
{

	_files_state.stayopen = 0;
	return __grend_files(&_files_state);
}

/*ARGSUSED*/
static int
_files_getgrent(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grscan_files(&rerror, &_files_group,
	    _files_groupbuf, sizeof(_files_groupbuf),
	    &_files_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*retval = &_files_group;
	return rv;
}

/*ARGSUSED*/
static int
_files_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	rv = __grscan_files(retval, grp, buffer, buflen,
	    &_files_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*result = grp;
	else
		*result = NULL;
	return rv;
}

/*ARGSUSED*/
static int
_files_getgrgid(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	gid_t		 gid	= va_arg(ap, gid_t);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_files(&_files_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_files(&rerror, &_files_group,
	    _files_groupbuf, sizeof(_files_groupbuf),
	    &_files_state, 1, NULL, gid);
	if (!_files_state.stayopen)
		__grend_files(&_files_state);
	if (rv == NS_SUCCESS)
		*retval = &_files_group;
	return rv;
}

/*ARGSUSED*/
static int
_files_getgrgid_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	gid_t		 gid	= va_arg(ap, gid_t);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_files state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid);
	__grend_files(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

/*ARGSUSED*/
static int
_files_getgrnam(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	const char	*name	= va_arg(ap, const char *);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_files(&_files_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_files(&rerror, &_files_group,
	    _files_groupbuf, sizeof(_files_groupbuf),
	    &_files_state, 1, name, 0);
	if (!_files_state.stayopen)
		__grend_files(&_files_state);
	if (rv == NS_SUCCESS)
		*retval = &_files_group;
	return rv;
}

/*ARGSUSED*/
static int
_files_getgrnam_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	const char	*name	= va_arg(ap, const char *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_files state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0);
	__grend_files(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

#ifdef HESIOD
		/*
		 *	dns methods
		 */

int
__grstart_dns(struct __grstate_dns *state)
{

	_DIAGASSERT(state != NULL);

	state->num = 0;
	if (state->context == NULL) {			/* setup Hesiod */
		if (hesiod_init(&state->context) == -1)
			return NS_UNAVAIL;
	}

	return NS_SUCCESS;
}

int
__grend_dns(struct __grstate_dns *state)
{

	_DIAGASSERT(state != NULL);

	state->num = 0;
	if (state->context) {
		hesiod_end(state->context);
		state->context = NULL;
	}
	return NS_SUCCESS;
}

/*
 * __grscan_dns
 *	Search Hesiod for the next desired entry.
 *	If search is zero, return the next entry.
 *	If search is non-zero, look for a specific name (if name != NULL),
 *	or a specific gid (if name == NULL).
 */
int
__grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen,
	struct __grstate_dns *state, int search, const char *name, gid_t gid)
{
	const char	**curzone;
	char		**hp, *ep;
	int		rv;

	static const char *zones_gid_group[] = {
		"gid",
		"group",
		NULL
	};

	static const char *zones_group[] = {
		"group",
		NULL
	};

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(state != NULL);
	/* name is NULL to indicate searching for gid */

	*retval = 0;

	if (state->context == NULL) {	/* only start if Hesiod not setup */
		rv = __grstart_dns(state);
		if (rv != NS_SUCCESS)
			return rv;
	}

 next_dns_entry:
	hp = NULL;
	rv = NS_NOTFOUND;

	if (! search) {			/* find next entry */
		if (state->num == -1)		/* exhausted search */
			return NS_NOTFOUND;
						/* find group-NNN */
		snprintf(buffer, buflen, "group-%u", state->num);
		state->num++;
		curzone = zones_group;
	} else if (name) {		/* find group name */
		snprintf(buffer, buflen, "%s", name);
		curzone = zones_group;
	} else {			/* find gid */
		snprintf(buffer, buflen, "%u", (unsigned int)gid);
		curzone = zones_gid_group;
	}

	for (; *curzone; curzone++) {		/* search zones */
		hp = hesiod_resolve(state->context, buffer, *curzone);
		if (hp != NULL)
			break;
		if (errno != ENOENT) {
			rv = NS_UNAVAIL;
			goto dnsgrscan_out;
		}
	}
	if (*curzone == NULL) {
		if (! search)
			state->num = -1;
		goto dnsgrscan_out;
	}

	if ((ep = strchr(hp[0], '\n')) != NULL)
		*ep = '\0';				/* clear trailing \n */
	if (_gr_parse(hp[0], grp, buffer, buflen)) {	/* validate line */
		if (! search) {				/* just want this one */
			rv = NS_SUCCESS;
		} else if ((name && strcmp(name, grp->gr_name) == 0) ||
		    (!name && gid == grp->gr_gid)) {	/* want specific */
			rv = NS_SUCCESS;
		}
	} else {					/* dodgy entry */
		if (!search) {			/* try again if ! searching */
			hesiod_free_list(state->context, hp);
			goto next_dns_entry;
		}
	}

 dnsgrscan_out:
	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
		*retval = errno;
	if (hp)
		hesiod_free_list(state->context, hp);
	return rv;
}

static struct __grstate_dns	_dns_state;
					/* storage for non _r functions */
static struct group		_dns_group;
static char			_dns_groupbuf[_GETGR_R_SIZE_MAX];

/*ARGSUSED*/
static int
_dns_setgrent(void *nsrv, void *nscb, va_list ap)
{

	_dns_state.stayopen = 0;
	return __grstart_dns(&_dns_state);
}

/*ARGSUSED*/
static int
_dns_setgroupent(void *nsrv, void *nscb, va_list ap)
{
	int	*retval		= va_arg(ap, int *);
	int	 stayopen	= va_arg(ap, int);

	int	rv;

	_dns_state.stayopen = stayopen;
	rv = __grstart_dns(&_dns_state);
	*retval = (rv == NS_SUCCESS);
	return rv;
}

/*ARGSUSED*/
static int
_dns_endgrent(void *nsrv, void *nscb, va_list ap)
{

	_dns_state.stayopen = 0;
	return __grend_dns(&_dns_state);
}

/*ARGSUSED*/
static int
_dns_getgrent(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);

	int	  rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grscan_dns(&rerror, &_dns_group,
	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*retval = &_dns_group;
	return rv;
}

/*ARGSUSED*/
static int
_dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	rv = __grscan_dns(retval, grp, buffer, buflen,
	    &_dns_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*result = grp;
	else
		*result = NULL;
	return rv;
}
/*ARGSUSED*/
static int
_dns_getgrgid(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	gid_t		 gid	= va_arg(ap, gid_t);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_dns(&_dns_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_dns(&rerror, &_dns_group,
	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid);
	if (!_dns_state.stayopen)
		__grend_dns(&_dns_state);
	if (rv == NS_SUCCESS)
		*retval = &_dns_group;
	return rv;
}

/*ARGSUSED*/
static int
_dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	gid_t		 gid	= va_arg(ap, gid_t);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_dns state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid);
	__grend_dns(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

/*ARGSUSED*/
static int
_dns_getgrnam(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	const char	*name	= va_arg(ap, const char *);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_dns(&_dns_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_dns(&rerror, &_dns_group,
	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0);
	if (!_dns_state.stayopen)
		__grend_dns(&_dns_state);
	if (rv == NS_SUCCESS)
		*retval = &_dns_group;
	return rv;
}

/*ARGSUSED*/
static int
_dns_getgrnam_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	const char	*name	= va_arg(ap, const char *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_dns state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0);
	__grend_dns(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

#endif /* HESIOD */

#ifdef YP
		/*
		 *	nis methods
		 */

int
__grstart_nis(struct __grstate_nis *state)
{

	_DIAGASSERT(state != NULL);

	state->done = 0;
	if (state->current) {
		free(state->current);
		state->current = NULL;
	}
	if (state->domain == NULL) {			/* setup NIS */
		switch (yp_get_default_domain(&state->domain)) {
		case 0:
			break;
		case YPERR_RESRC:
			return NS_TRYAGAIN;
		default:
			return NS_UNAVAIL;
		}
	}
	return NS_SUCCESS;
}

int
__grend_nis(struct __grstate_nis *state)
{

	_DIAGASSERT(state != NULL);

	if (state->domain) {
		state->domain = NULL;
	}
	state->done = 0;
	if (state->current) {
		free(state->current);
		state->current = NULL;
	}
	return NS_SUCCESS;
}

/*
 * __grscan_nis
 *	Search NIS for the next desired entry.
 *	If search is zero, return the next entry.
 *	If search is non-zero, look for a specific name (if name != NULL),
 *	or a specific gid (if name == NULL).
 */
int
__grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen,
	struct __grstate_nis *state, int search, const char *name, gid_t gid)
{
	const char *map;
	char	*key, *data;
	int	nisr, rv, keylen, datalen;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(state != NULL);
	/* name is NULL to indicate searching for gid */

	*retval = 0;

	if (state->domain == NULL) {	/* only start if NIS not setup */
		rv = __grstart_nis(state);
		if (rv != NS_SUCCESS)
			return rv;
	}

 next_nis_entry:
	key = NULL;
	data = NULL;
	rv = NS_SUCCESS;

	if (! search) 	{			/* find next entry */
		if (state->done)			/* exhausted search */
			return NS_NOTFOUND;
		map = "group.byname";
		if (state->current) {			/* already searching */
			nisr = yp_next(state->domain, map,
			    state->current, state->currentlen,
			    &key, &keylen, &data, &datalen);
			free(state->current);
			state->current = NULL;
			switch (nisr) {
			case 0:
				state->current = key;
				state->currentlen = keylen;
				key = NULL;
				break;
			case YPERR_NOMORE:
				rv = NS_NOTFOUND;
				state->done = 1;
				break;
			default:
				rv = NS_UNAVAIL;
				break;
			}
		} else {				/* new search */
			if (yp_first(state->domain, map,
			    &state->current, &state->currentlen,
			    &data, &datalen)) {
				rv = NS_UNAVAIL;
			}
		}
	} else {				/* search for specific item */
		if (name) {			/* find group name */
			snprintf(buffer, buflen, "%s", name);
			map = "group.byname";
		} else {			/* find gid */
			snprintf(buffer, buflen, "%u", (unsigned int)gid);
			map = "group.bygid";
		}
		nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
		    &data, &datalen);
		switch (nisr) {
		case 0:
			break;
		case YPERR_KEY:
			rv = NS_NOTFOUND;
			break;
		default:
			rv = NS_UNAVAIL;
			break;
		}
	}
	if (rv == NS_SUCCESS) {				/* validate data */
		data[datalen] = '\0';			/* clear trailing \n */
		if (_gr_parse(data, grp, buffer, buflen)) {
			if (! search) {			/* just want this one */
				rv = NS_SUCCESS;
			} else if ((name && strcmp(name, grp->gr_name) == 0) ||
			    (!name && gid == grp->gr_gid)) {
							/* want specific */
				rv = NS_SUCCESS;
			}
		} else {				/* dodgy entry */
			if (!search) {		/* try again if ! searching */
				free(data);
				goto next_nis_entry;
			}
		}
	}

	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
		*retval = errno;
	if (key)
		free(key);
	if (data)
		free(data);
	return rv;
}

static struct __grstate_nis	_nis_state;
					/* storage for non _r functions */
static struct group		_nis_group;
static char			_nis_groupbuf[_GETGR_R_SIZE_MAX];

/*ARGSUSED*/
static int
_nis_setgrent(void *nsrv, void *nscb, va_list ap)
{

	_nis_state.stayopen = 0;
	return __grstart_nis(&_nis_state);
}

/*ARGSUSED*/
static int
_nis_setgroupent(void *nsrv, void *nscb, va_list ap)
{
	int	*retval		= va_arg(ap, int *);
	int	 stayopen	= va_arg(ap, int);

	int	rv;

	_nis_state.stayopen = stayopen;
	rv = __grstart_nis(&_nis_state);
	*retval = (rv == NS_SUCCESS);
	return rv;
}

/*ARGSUSED*/
static int
_nis_endgrent(void *nsrv, void *nscb, va_list ap)
{

	return __grend_nis(&_nis_state);
}

/*ARGSUSED*/
static int
_nis_getgrent(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grscan_nis(&rerror, &_nis_group,
	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*retval = &_nis_group;
	return rv;
}

/*ARGSUSED*/
static int
_nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	rv = __grscan_nis(retval, grp, buffer, buflen,
	    &_nis_state, 0, NULL, 0);
	if (rv == NS_SUCCESS)
		*result = grp;
	else
		*result = NULL;
	return rv;
}

/*ARGSUSED*/
static int
_nis_getgrgid(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	gid_t		 gid	= va_arg(ap, gid_t);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_nis(&_nis_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_nis(&rerror, &_nis_group,
	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid);
	if (!_nis_state.stayopen)
		__grend_nis(&_nis_state);
	if (rv == NS_SUCCESS)
		*retval = &_nis_group;
	return rv;
}

/*ARGSUSED*/
static int
_nis_getgrgid_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	gid_t		 gid	= va_arg(ap, gid_t);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_nis state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
/* remark: we run under a global mutex inside of this module ... */
	if (_nis_state.stayopen)
	  { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
	     rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, NULL, gid);
	  }
	else
	  {
	    memset(&state, 0, sizeof(state));
	    rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
	    __grend_nis(&state);
	  }
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

/*ARGSUSED*/
static int
_nis_getgrnam(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	const char	*name	= va_arg(ap, const char *);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_nis(&_nis_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_nis(&rerror, &_nis_group,
	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0);
	if (!_nis_state.stayopen)
		__grend_nis(&_nis_state);
	if (rv == NS_SUCCESS)
		*retval = &_nis_group;
	return rv;
}

/*ARGSUSED*/
static int
_nis_getgrnam_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	const char	*name	= va_arg(ap, const char *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_nis state;
	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
/* remark: we run under a global mutex inside of this module ... */
	if (_nis_state.stayopen)
	  { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
	     rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, name, 0);
	  }
	else
	  {
	    memset(&state, 0, sizeof(state));
	    rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
	    __grend_nis(&state);
	  }
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

#endif /* YP */

#ifdef _GROUP_COMPAT
		/*
		 *	compat methods
		 */

int
__grstart_compat(struct __grstate_compat *state)
{

	_DIAGASSERT(state != NULL);

	if (state->fp == NULL) {
		state->fp = fopen(_PATH_GROUP, "re");
		if (state->fp == NULL)
			return NS_UNAVAIL;
	} else {
		rewind(state->fp);
	}
	return NS_SUCCESS;
}

int
__grend_compat(struct __grstate_compat *state)
{

	_DIAGASSERT(state != NULL);

	if (state->name) {
		free(state->name);
		state->name = NULL;
	}
	if (state->fp) {
		(void) fclose(state->fp);
		state->fp = NULL;
	}
	return NS_SUCCESS;
}

/*
 * __grbad_compat
 *	log an error if "files" or "compat" is specified in
 *	group_compat database
 */
/*ARGSUSED*/
int
__grbad_compat(void *nsrv, void *nscb, va_list ap)
{
	static int warned;

	_DIAGASSERT(nsrv != NULL);
	_DIAGASSERT(nscb != NULL);

	if (!warned) {
		syslog(LOG_ERR,
			"nsswitch.conf group_compat database can't use '%s'",
			(const char *)nscb);
	}
	warned = 1;
	return NS_UNAVAIL;
}

/*
 * __grscan_compat
 *	Scan state->fp for the next desired entry.
 *	If search is zero, return the next entry.
 *	If search is non-zero, look for a specific name (if name != NULL),
 *	or a specific gid (if name == NULL).
 *	Sets *retval to the errno if the result is not NS_SUCCESS or
 *	NS_NOTFOUND.
 *
 *	searchfunc is invoked when a compat "+" lookup is required;
 *	searchcookie is passed as the first argument to searchfunc,
 *	the second argument is the group result.
 *	This should return NS_NOTFOUND when "no more groups" from compat src.
 *	If searchfunc is NULL then nsdispatch of getgrent is used.
 *	This is primarily intended for getgroupmembership(3)'s compat backend.
 */
int
__grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
	struct __grstate_compat *state, int search, const char *name, gid_t gid,
	int (*searchfunc)(void *, struct group **), void *searchcookie)
{
	int		rv;
	char		filebuf[_GETGR_R_SIZE_MAX], *ep;

	static const ns_dtab compatentdtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_getgrent_r, NULL)
		NS_NIS_CB(_nis_getgrent_r, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};
	static const ns_dtab compatgiddtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_getgrgid_r, NULL)
		NS_NIS_CB(_nis_getgrgid_r, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};
	static const ns_dtab compatnamdtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_getgrnam_r, NULL)
		NS_NIS_CB(_nis_getgrnam_r, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(state != NULL);
	/* name is NULL to indicate searching for gid */

	*retval = 0;

	if (state->fp == NULL) {	/* only start if file not open yet */
		rv = __grstart_compat(state);
		if (rv != NS_SUCCESS)
			goto compatgrscan_out;
	}
	rv = NS_NOTFOUND;

	for (;;) {					/* loop through file */
		if (state->name != NULL) {
					/* processing compat entry */
			int		crv, cretval;
			struct group	cgrp, *cgrpres;

			if (state->name[0]) {		/* specific +group: */
				crv = nsdispatch(NULL, compatnamdtab,
				    NSDB_GROUP_COMPAT, "getgrnam_r",
				    __nsdefaultnis,
				    &cretval, state->name,
				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
				free(state->name);	/* (only check 1 grp) */
				state->name = NULL;
			} else if (!search) {		/* any group */
				if (searchfunc) {
					crv = searchfunc(searchcookie,
					    &cgrpres);
				} else {
					crv = nsdispatch(NULL, compatentdtab,
					    NSDB_GROUP_COMPAT, "getgrent_r",
					    __nsdefaultnis,
					    &cretval, &cgrp, filebuf,
					    sizeof(filebuf), &cgrpres);
				}
			} else if (name) {		/* specific group */
				crv = nsdispatch(NULL, compatnamdtab,
				    NSDB_GROUP_COMPAT, "getgrnam_r",
				    __nsdefaultnis,
				    &cretval, name,
				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
			} else {			/* specific gid */
				crv = nsdispatch(NULL, compatgiddtab,
				    NSDB_GROUP_COMPAT, "getgrgid_r",
				    __nsdefaultnis,
				    &cretval, gid,
				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
			}
			if (crv != NS_SUCCESS) {	/* not found */
				free(state->name);
				state->name = NULL;
				continue;		/* try next line */
			}
			if (!_gr_copy(cgrpres, grp, buffer, buflen)) {
				rv = NS_UNAVAIL;
				break;
			}
			goto compatgrscan_cmpgrp;	/* skip to grp test */
		}

							/* get next file line */
		if (fgets(filebuf, (int)sizeof(filebuf), state->fp) == NULL)
			break;

		ep = strchr(filebuf, '\n');
		if (ep == NULL) {	/* skip lines that are too big */
			int ch;

			while ((ch = getc(state->fp)) != '\n' && ch != EOF)
				continue;
			continue;
		}
		*ep = '\0';				/* clear trailing \n */

		if (filebuf[0] == '+') {		/* parse compat line */
			if (state->name)
				free(state->name);
			state->name = NULL;
			switch(filebuf[1]) {
			case ':':
			case '\0':
				state->name = strdup("");
				break;
			default:
				ep = strchr(filebuf + 1, ':');
				if (ep == NULL)
					break;
				*ep = '\0';
				state->name = strdup(filebuf + 1);
				break;
			}
			if (state->name == NULL) {
				rv = NS_UNAVAIL;
				break;
			}
			continue;
		}

							/* validate line */
		if (! _gr_parse(filebuf, grp, buffer, buflen)) {
			continue;			/* skip bad lines */
		}

 compatgrscan_cmpgrp:
		if (! search) {				/* just want this one */
			rv = NS_SUCCESS;
			break;
		}
							/* want specific */
		if ((name && strcmp(name, grp->gr_name) == 0) ||
		    (!name && gid == grp->gr_gid)) {
			rv = NS_SUCCESS;
			break;
		}

	}

 compatgrscan_out:
	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
		*retval = errno;
	return rv;
}

static struct __grstate_compat	_compat_state;
					/* storage for non _r functions */
static struct group		_compat_group;
static char			_compat_groupbuf[_GETGR_R_SIZE_MAX];

/*ARGSUSED*/
static int
_compat_setgrent(void *nsrv, void *nscb, va_list ap)
{
	static const ns_dtab dtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_setgrent, NULL)
		NS_NIS_CB(_nis_setgrent, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};

					/* force group_compat setgrent() */
	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgrent",
	    __nsdefaultnis_forceall);

					/* reset state, keep fp open */
	_compat_state.stayopen = 0;
	return __grstart_compat(&_compat_state);
}

/*ARGSUSED*/
static int
_compat_setgroupent(void *nsrv, void *nscb, va_list ap)
{
	int	*retval		= va_arg(ap, int *);
	int	 stayopen	= va_arg(ap, int);

	int	rv;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_setgroupent, NULL)
		NS_NIS_CB(_nis_setgroupent, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};

					/* force group_compat setgroupent() */
	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent",
	    __nsdefaultnis_forceall, &rv, stayopen);

	_compat_state.stayopen = stayopen;
	rv = __grstart_compat(&_compat_state);
	*retval = (rv == NS_SUCCESS);
	return rv;
}

/*ARGSUSED*/
static int
_compat_endgrent(void *nsrv, void *nscb, va_list ap)
{
	static const ns_dtab dtab[] = {
		NS_FILES_CB(__grbad_compat, "files")
		NS_DNS_CB(_dns_endgrent, NULL)
		NS_NIS_CB(_nis_endgrent, NULL)
		NS_COMPAT_CB(__grbad_compat, "compat")
		NS_NULL_CB
	};

					/* force group_compat endgrent() */
	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent",
	    __nsdefaultnis_forceall);

					/* reset state, close fp */
	_compat_state.stayopen = 0;
	return __grend_compat(&_compat_state);
}

/*ARGSUSED*/
static int
_compat_getgrent(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grscan_compat(&rerror, &_compat_group,
	    _compat_groupbuf, sizeof(_compat_groupbuf),
	    &_compat_state, 0, NULL, 0, NULL, NULL);
	if (rv == NS_SUCCESS)
		*retval = &_compat_group;
	return rv;
}

/*ARGSUSED*/
static int
_compat_getgrent_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	int	rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	rv = __grscan_compat(retval, grp, buffer, buflen,
	    &_compat_state, 0, NULL, 0, NULL, NULL);
	if (rv == NS_SUCCESS)
		*result = grp;
	else
		*result = NULL;
	return rv;
}

/*ARGSUSED*/
static int
_compat_getgrgid(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	gid_t		 gid	= va_arg(ap, gid_t);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_compat(&_compat_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_compat(&rerror, &_compat_group,
	    _compat_groupbuf, sizeof(_compat_groupbuf),
	    &_compat_state, 1, NULL, gid, NULL, NULL);
	if (!_compat_state.stayopen)
		__grend_compat(&_compat_state);
	if (rv == NS_SUCCESS)
		*retval = &_compat_group;
	return rv;
}

/*ARGSUSED*/
static int
_compat_getgrgid_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	gid_t		 gid	= va_arg(ap, gid_t);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_compat	state;
	int		rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_compat(retval, grp, buffer, buflen, &state,
	    1, NULL, gid, NULL, NULL);
	__grend_compat(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

/*ARGSUSED*/
static int
_compat_getgrnam(void *nsrv, void *nscb, va_list ap)
{
	struct group	**retval = va_arg(ap, struct group **);
	const char	*name	= va_arg(ap, const char *);

	int	rv, rerror;

	_DIAGASSERT(retval != NULL);

	*retval = NULL;
	rv = __grstart_compat(&_compat_state);
	if (rv != NS_SUCCESS)
		return rv;
	rv = __grscan_compat(&rerror, &_compat_group,
	    _compat_groupbuf, sizeof(_compat_groupbuf),
	    &_compat_state, 1, name, 0, NULL, NULL);
	if (!_compat_state.stayopen)
		__grend_compat(&_compat_state);
	if (rv == NS_SUCCESS)
		*retval = &_compat_group;
	return rv;
}

/*ARGSUSED*/
static int
_compat_getgrnam_r(void *nsrv, void *nscb, va_list ap)
{
	int		*retval	= va_arg(ap, int *);
	const char	*name	= va_arg(ap, const char *);
	struct group	*grp	= va_arg(ap, struct group *);
	char		*buffer	= va_arg(ap, char *);
	size_t		 buflen	= va_arg(ap, size_t);
	struct group   **result	= va_arg(ap, struct group **);

	struct __grstate_compat	state;
	int		rv;

	_DIAGASSERT(retval != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	memset(&state, 0, sizeof(state));
	rv = __grscan_compat(retval, grp, buffer, buflen, &state,
	    1, name, 0, NULL, NULL);
	__grend_compat(&state);
	if (rv == NS_SUCCESS)
		*result = grp;
	return rv;
}

#endif	/* _GROUP_COMPAT */

		/*
		 *	public functions
		 */

struct group *
getgrent(void)
{
	int		rv;
	struct group	*retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrent, NULL)
		NS_DNS_CB(_dns_getgrent, NULL)
		NS_NIS_CB(_nis_getgrent, NULL)
		NS_COMPAT_CB(_compat_getgrent, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat,
	    &retval);
	mutex_unlock(&__grmutex);
	return (rv == NS_SUCCESS) ? retval : NULL;
}

int
getgrent_r(struct group *grp, char *buffer, size_t buflen,
    struct group **result)
{
	int		rv, retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrent_r, NULL)
		NS_DNS_CB(_dns_getgrent_r, NULL)
		NS_NIS_CB(_nis_getgrent_r, NULL)
		NS_COMPAT_CB(_compat_getgrent_r, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat,
	    &retval, grp, buffer, buflen, result);
	mutex_unlock(&__grmutex);
	switch (rv) {
	case NS_SUCCESS:
	case NS_NOTFOUND:
		return 0;
	default:
		return retval;
	}
}

struct group *
getgrgid(gid_t gid)
{
	int		rv;
	struct group	*retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrgid, NULL)
		NS_DNS_CB(_dns_getgrgid, NULL)
		NS_NIS_CB(_nis_getgrgid, NULL)
		NS_COMPAT_CB(_compat_getgrgid, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid", __nsdefaultcompat,
	    &retval, gid);
	mutex_unlock(&__grmutex);
	return (rv == NS_SUCCESS) ? retval : NULL;
}

int
getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t buflen,
	struct group **result)
{
	int	rv, retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrgid_r, NULL)
		NS_DNS_CB(_dns_getgrgid_r, NULL)
		NS_NIS_CB(_nis_getgrgid_r, NULL)
		NS_COMPAT_CB(_compat_getgrgid_r, NULL)
		NS_NULL_CB
	};

	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	retval = 0;
	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid_r", __nsdefaultcompat,
	    &retval, gid, grp, buffer, buflen, result);
	mutex_unlock(&__grmutex);
	switch (rv) {
	case NS_SUCCESS:
	case NS_NOTFOUND:
		return 0;
	default:
		return retval;
	}
}

struct group *
getgrnam(const char *name)
{
	int		rv;
	struct group	*retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrnam, NULL)
		NS_DNS_CB(_dns_getgrnam, NULL)
		NS_NIS_CB(_nis_getgrnam, NULL)
		NS_COMPAT_CB(_compat_getgrnam, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat,
	    &retval, name);
	mutex_unlock(&__grmutex);
	return (rv == NS_SUCCESS) ? retval : NULL;
}

int
getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen,
	struct group **result)
{
	int	rv, retval;

	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_getgrnam_r, NULL)
		NS_DNS_CB(_dns_getgrnam_r, NULL)
		NS_NIS_CB(_nis_getgrnam_r, NULL)
		NS_COMPAT_CB(_compat_getgrnam_r, NULL)
		NS_NULL_CB
	};

	_DIAGASSERT(name != NULL);
	_DIAGASSERT(grp != NULL);
	_DIAGASSERT(buffer != NULL);
	_DIAGASSERT(result != NULL);

	*result = NULL;
	retval = 0;
	mutex_lock(&__grmutex);
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat,
	    &retval, name, grp, buffer, buflen, result);
	mutex_unlock(&__grmutex);
	switch (rv) {
	case NS_SUCCESS:
	case NS_NOTFOUND:
		return 0;
	default:
		return retval;
	}
}

void
endgrent(void)
{
	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_endgrent, NULL)
		NS_DNS_CB(_dns_endgrent, NULL)
		NS_NIS_CB(_nis_endgrent, NULL)
		NS_COMPAT_CB(_compat_endgrent, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
					/* force all endgrent() methods */
	(void) nsdispatch(NULL, dtab, NSDB_GROUP, "endgrent",
	    __nsdefaultcompat_forceall);
	mutex_unlock(&__grmutex);
}

int
setgroupent(int stayopen)
{
	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_setgroupent, NULL)
		NS_DNS_CB(_dns_setgroupent, NULL)
		NS_NIS_CB(_nis_setgroupent, NULL)
		NS_COMPAT_CB(_compat_setgroupent, NULL)
		NS_NULL_CB
	};
	int	rv, retval;

	mutex_lock(&__grmutex);
					/* force all setgroupent() methods */
	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent",
	    __nsdefaultcompat_forceall, &retval, stayopen);
	mutex_unlock(&__grmutex);
	return (rv == NS_SUCCESS) ? retval : 0;
}

void
setgrent(void)
{
	static const ns_dtab dtab[] = {
		NS_FILES_CB(_files_setgrent, NULL)
		NS_DNS_CB(_dns_setgrent, NULL)
		NS_NIS_CB(_nis_setgrent, NULL)
		NS_COMPAT_CB(_compat_setgrent, NULL)
		NS_NULL_CB
	};

	mutex_lock(&__grmutex);
					/* force all setgrent() methods */
	(void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent",
	    __nsdefaultcompat_forceall);
	mutex_unlock(&__grmutex);
}

redpajama_set_name: RedPajamaGithub


text:
var Emitter = require('emitter');
var resize = require('resize');
// var dimensions = require('dimensions');

module.exports = parentList;

var uFlexID = 0;

function parentList(divValue, reqOptions)
{
	// console.log(divValue);

	var self = this;

	if(!reqOptions || !reqOptions.objectSize || !reqOptions.objectSize.width || !reqOptions.objectSize.height)
		throw new Error("Can't use flexforever without options or objectSize");

	//deep clone the required options object
	reqOptions = JSON.parse(JSON.stringify(reqOptions));

	//prepend the new objects
	self.append = reqOptions.append || false;

	//add emitter properties to this object
	Emitter(self);

	//add appropriate classes to our given div
	self.uid = "plist" + uFlexID++;

	self.objectSize = reqOptions.objectSize;
	// console.log(reqOptions.maxItemCount);
	//we auto determin
	self.autoDetermineMax = reqOptions.autoDetermineMax == undefined ? true : reqOptions.autoDetermineMax;

	self.maxItemCount = reqOptions.maxItemCount || Number.MAX_VALUE;

	reqOptions.extraHeightPerObject = reqOptions.extraHeightPerObject || 0;

	//add a certain amount to our height object to compensate for any additional padding
	self.objectSize.height = self.objectSize.height + reqOptions.extraHeightPerObject;

	var plistBase = self.uid + "-#@#";
	var outerFlexID = plistBase.replace(/#@#/g, "container");

	//set the innerHTML of the supplied div to now be setup for swiper integration
	divValue.innerHTML = "
"
	+ "
";

	var outerContainer = document.querySelector("#" + outerFlexID);

	var itemsPerColumn = function()
	{
		return Math.floor(outerContainer.offsetHeight/(self.objectSize.height + 2*(self.objectSize.columnMargin || 0 + self.borderSize)));
	}

	if(self.autoDetermineMax)
	{
		self.maxItemCount = itemsPerColumn();
		// console.log("Max items: ", self.maxItemCount);
	}

	resize.bind(outerContainer, function()
	{
		//we've received a resize event
		//adjust element counts and the like
		if(self.autoDetermineMax)
			self.maxItemCount = itemsPerColumn();

		// console.log("Size change deteced, max items: ", self.maxItemCount);

		if(activeElements > self.maxItemCount)
		{
			//don't remove EVERYTHING -- need to leave 1 element no matter what size
			var max = Math.max(1, self.maxItemCount);

			for(var i = max; i < activeElements; i++)
			{
				//remove oldest first always -- however many times we need to do this
				self.removeOldest();
			}
		}
	})

	self.borderSize = 1;

	var nextItem = 0;
	var activeElements = 0;

	var htmlObjects = {};
	var dataObjects = {};

	//internal create the parent
	function internalCreate(i, data)
	{
		// console.log("\t\thapkjsdflkjsdflkjsdlfkj: calling create: ", i, " d: ", data)
		var el = createElement(i);
		htmlObjects[i] = el;
		dataObjects[i] = data;
		activeElements++;
		self.emit('elementCreated', data, i, el);
		return el;
	}

	self.activeParents = function(){return activeElements;};

	//really simple, just append to our container a new element
	self.addElement = function(data)
	{
		var newID = nextItem++;

		var el = internalCreate(newID, data);

		// console.log("activeElements: ", activeElements, " count: ", self.maxItemCount)
			//need to remove the lowest element
		if(activeElements > self.maxItemCount)
			self.removeOldest();

		//prepend
		if(!self.append)
			outerContainer.insertBefore(el, outerContainer.firstChild);
		else //otherwise we're appending the object
			outerContainer.append(el);
	}
	self.removeOldest = function()
	{
		var keys = Object.keys(htmlObjects);
		keys.sort(function(a,b){return parseInt(a) - parseInt(b);});

		//grab the lowest key we have
		var rmKey = keys[0];

		//now we remove that object at the bottom of the list
		self.removeElement(rmKey);
	}

	self.removeElement = function(id)
	{
		// console.log("Removing: ", id);
		//get the object from our list of objects
		var el = htmlObjects[id];
		var data = dataObjects[id];

		//minus an element
		activeElements--;

		//let it be known, it's over! We're about to remove the parent
		self.emit('elementRemoved', data, id);

		//remove the object!
		outerContainer.removeChild(el);

		delete htmlObjects[id];
		delete dataObjects[id];

	}

	self.removeRandom = function()
	{
		var keys = Object.keys(htmlObjects);
		var rmIx = Math.floor(Math.random()*keys.length);

		//jusst remove something random -- for testing purposes
		self.removeElement(keys[rmIx]);
	}

	var objectIDToUID = function(idCount)
	{
		return self.uid + "-object-" + idCount;
	}

	var getElement = function(ix)
	{
		var objectUID = objectIDToUID(ix);
		return htmlObjects[objectUID];
	}

	//create an element from scratch (using the given identifier)
	var createElement = function(ix)
	{
		var element = document.createElement('div');
		var objectUID = objectIDToUID(ix);

		element.id = objectUID;
		element.style.width = self.objectSize.width + "px";
		element.style.height = self.objectSize.height + "px";

		element.style.marginLeft = self.objectSize.rowMargin + "px" || 0;
		element.style.marginRight = self.objectSize.rowMargin + "px" || 0;

		element.style.marginTop = self.objectSize.columnMargin + "px" || 0;
		element.style.marginBottom = self.objectSize.columnMargin + "px" || 0;

		// element.style.border = (self.borderSize ? (self.borderSize + "px solid black") : 0);

		//make it a border class element
		element.className += "border pobject";

		element.style.overflow = "hidden";

		return element;
	}

	return self;
}


text:
'use strict';

module.exports = function(app) {
  app.controller('NavController', ['$rootScope', 'AuthService', function($rs, AuthService) {

    let ctrl = this;
    ctrl.signout = AuthService.signout;

    let $window = $(window);
    let $hamMenu = $('#hamburger-menu-icon');
    let $navBar = $('nav-bar');
    let $navMenu = $('#nav-menu');
    let $navLink = $('.nav-link');
    let $linkTitle = $('.link-title');

    ctrl.toggleMenu = function($el) {
      $el.toggleClass('open');
      $navMenu.toggleClass('open');
    }

    ctrl.menuListener = function() {
      $hamMenu.on('click', () => {
        ctrl.toggleMenu($hamMenu);
      });

      $navLink.on({
        mouseenter: function(e) {
          $linkTitle.html($(this).attr('data-title'));
        },
        mouseleave: function(e) {
          $linkTitle.html('');
        },
      });
    }

    ctrl.init = function() {
      ctrl.menuListener();
    }

    ctrl.init();
  }]);
};


text:
import { Mark } from 'vega-lite/build/src/mark';
import { Channel } from 'vega-lite/build/src/channel';

export function capitalizeFirstLetter(string: string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

let id: number = 0;

export function assert(s: string, name?: string) {
  // return `(assert ${s})\n\n`;
  return `(assert (! ${s} :named c${name || id++}))\n\n`;
}

export function assertSoft(s: string, weight: number) {
  return `(assert-soft ${s} :weight ${weight})\n\n`;
}

export function implies(a: string, b: string) {
  return `(=> ${a} ${b})\n`;
}

export function and(...exprs: string[]) {
  return `(and
  ${exprs.join("\n")}
  )`;
}

export function or(...exprs: string[]) {
  return `(or
  ${exprs.join("\n")}
  )`;
}

export function eq(a: string, b: string) {
  return `(= ${a} ${b})`;
}

export function not(s) {
  return `(not ${s})`;
}

export function mark(m: Mark) {
  return eq("mark", capitalizeFirstLetter(m) + "Mark");
}

// TODO: make e Encoding
export function channel(e: string, c: Channel) {
  return eq(`(channel ${e})`, capitalizeFirstLetter(c) + "Channel");
}

// TODO: add aggregate, type, ...

export function iteFromDictFlipKeyValue(getValueExpr, dict, lastElseValue = "10000"){

  // dict should be exhaustive
  // todo: lowp check values in dict are proper

  /*
   *  Recurse through dict
   * */
  const helper = ([head, ...tail]) => {
    if (head === undefined)
      return `${lastElseValue}`;
    else {
      const [key, value] = head;

      return `(ite (= ${getValueExpr} ${value} ) ${key}
                ${helper(tail)})`;
    }
  };

   return helper((Object as any).entries(dict));
}


text:
This project provides Converter to convert generic xsd/xml to asvc/avro files.
Avro schema and avro file are generated from xsd schema and xml file.

Additionally it includes simple schemaless converter that converts xml to avro and avro to xml.

## Running Project
1. git clone;
2. mvn package;
3. java -jar target/xml-avro*.jar <xsdFile> <xmlFile> {<avscFile>} {<avroFile>} // converts specified xml+xsd to avro+asvc files
4. java -cp target/xml-avro*.jar ly.stealth.xmlavro.simple.Converter avro <xmlFile> <avroFile> // convert xml to avro
5. java -cp target/xml-avro*.jar ly.stealth.xmlavro.simple.Converter xml <avroFile> <xmlFile> // convert avro to xml

## Schema-based converter
Usage:
```
XML Avro converter.
Usage: "{-d|--debug} {-b|--baseDir <baseDir>} <xsdFile> <xmlFile> {<avscFile>} {<avroFile>}"
```
## Restrictions
Schema-based converter currently only supports conversion in one direction: from xml to avro.

Converter has following restriction:
- xml docs with multiple namespaces are not supported;
- complex type extensions are not supported;

## Simple converter
Usage:
```
{avro|xml} <inFile> <outFile>
```
Note: simple converter uses predefined general avro schema located at src/ly/stealth/xmlavro/simple/xml.avsc


text: <SiloListingRequest session-id="${session-id}" sync-id="${sync-id}"/>


text:
<Namespace Name="Hyena.Downloader">
  <Docs>
    <summary>To be added.</summary>
    <remarks>To be added.</remarks>
  </Docs>
</Namespace>


text:
package fr.ensimag.cannonball;

import org.opencv.core.Mat;
import org.opencv.core.Size;

public class CameraParameters {

	//#include "exports.h"
	//#include <opencv2/core/core.hpp>

	// 3x3 matrix (fx 0 cx, 0 fy cy, 0 0 1)
	Mat  CameraMatrix;
	//4x1 matrix (k1,k2,p1,p2)
	Mat  Distorsion;
	//size of the image
	Size CamSize;

}


text:
package net.runelite.api.widgets;

public final class WidgetTextAlignment
{
	public static final int LEFT = 0;
	public static final int TOP = 0;
	public static final int CENTER = 1;
	public static final int RIGHT = 2;
	public static final int BOTTOM = 2;
}


text:
<?php

/**
 * This file is part of the Spryker Demoshop.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Orm\Zed\Locale\Persistence;

use Spryker\Zed\Locale\Persistence\Propel\AbstractSpyLocaleQuery as BaseSpyLocaleQuery;

/**
 * Skeleton subclass for performing query and update operations on the 'spy_locale' table.
 *
 *
 *
 * You should add additional methods to this class to meet the
 * application requirements. This class will only be generated as
 * long as it does not already exist in the output directory.
 */
class SpyLocaleQuery extends BaseSpyLocaleQuery
{
}


text:
package org.bouncycastle.pqc.jcajce.provider.test;

import org.bouncycastle.util.Arrays;

public class PQCSigUtils
{
    static class SigWrapper
    {
        private final byte[] sig;

        SigWrapper(byte[] sig)
        {
            this.sig = sig;
        }

        public boolean equals(Object o)
        {
            if (o instanceof SigWrapper)
            {
                SigWrapper other = (SigWrapper)o;

                return Arrays.areEqual(other.sig, this.sig);
            }

            return false;
        }

        public int hashCode()
        {
            return Arrays.hashCode(this.sig);
        }
    }
}


text:
const assert = require('assert');
const CommonCommands = require('../commands/helperCommandsClass.js');

class PageCommands extends CommonCommands {
  constructor() {
    super();

    assert.strictEqual(this.api.sessionId, '1352110219202');
    assert.strictEqual(this.browser.sessionId, '1352110219202');
    assert.strictEqual(this.client.api.sessionId, '1352110219202');
    assert.ok(this.transportActions);
    assert.ok(this.driver);
    assert.ok(typeof this.httpRequest == 'function');
    assert.ok(typeof this.toString == 'function');
  }

  basicCommand() {
    const basic = super.basicCommand();

    return {
      ...basic,
      otherResult: 'from-other-helper-class'
    };
  }
}

module.exports = {
  url: 'http://localhost.com',
  elements: {
    loginAsString: '#weblogin',
    loginCss: {selector: '#weblogin'},
    loginIndexed: {
      selector: '#weblogin',
      index: 1
    },
    loginXpath: {
      selector: '//weblogin',
      locateStrategy: 'xpath'
    },
    loginId: {
      selector: 'weblogin',
      locateStrategy: 'id'
    }
  },

  commands: PageCommands
};