#! /bin/sh

# Verify prerequisites
for cmd in cc mktemp getent gzip sed strace xxd; do
    if [ -z "$(type -p "$cmd")" ]; then
        echo "Please install missing $cmd" >&2; exit 1
    fi
done

# Find a non-existent group
i=0; while : ; do
    grp0="xyzzy$i"
    if [ -z "$(getent group "$grp0")" ]; then break; fi
    i=$((i + 1))
done

# Find an existent group
grp1=$(getent group | sed 's/:.*//' | head -n1)
if [ -z "$grp1" ]; then
    echo "$0: ERROR: getent group returned no output" >&2; exit 1
fi
if [ -z "$(getent group "$grp1")" ]; then
    echo "$0: ERROR: getent group fails for: $grp1" >&2; exit 1
fi

# Create a scratch directory and compile getgrnam.c there
tmp=$(mktemp -d /tmp/debug.XXXXXX)
case $tmp in
/tmp/debug.*) : ;;
*) echo "$0: Error: Unexpected mktemp result: $tmp" >&2; exit 1;;
esac
trap "rm -rf '$tmp'; exit" EXIT HUP INT QUIT TERM
cd "$tmp" || exit 1
cat <<\__END__ > getgrnam.c
#include <sys/types.h>
#include <grp.h>
#include <errno.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    char buf[1024];
    struct group g, *p;
    int rc;
    errno = 0;
    rc = getgrnam_r(argc > 1 ? argv[1] : "nosuchgrouphere",
                    &g, buf, sizeof(buf), &p);
    printf("%s(%p) %m(%d)\n", p ? g.gr_name : NULL, p, errno);
    return (rc == 0 && p == NULL);
}
__END__
cc -o getgrnam getgrnam.c

echo "/etc/nsswitch.conf group entry"
grep '^group' /etc/nsswitch.conf

for g in "$grp0" "$grp1"
do
    echo "== Tracing getent group $g"
    strace -o trace.out getent group "$g"
    gzip -c trace.out | xxd -p -c39

    echo "== Tracing getgrnam $g"
    strace -o trace.out ./getgrnam "$g"
    gzip -c trace.out | xxd -p -c39
done
