/*
 *----------------------------------------------------------------------
 *           "THE BEER-WARE LICENSE" (Revision 42):
 * <jeang3nie@HitchHiker-Linux.org> wrote this file. As long as you
 * retain this notice you can do whatever you want with this stuff. If
 * we meet some day, and you think this stuff is worth it, you can buy
 * me a beer in return.
 * ---------------------------------------------------------------------
 *            ______   _______  _          _________
 *           (  __  \ (  ___  )( (    /|( )\__   __/
 *           | (  \  )| (   ) ||  \  ( ||/    ) (
 *           | |   ) || |   | ||   \ | |      | |
 *           | |   | || |   | || (\ \) |      | |
 *           | |   ) || |   | || | \   |      | |
 *           | (__/  )| (___) || )  \  |      | |
 *           (______/ (_______)|/    )_)      )_(
 *
 *         _______  _______  _       _________ _______
 *        (  ____ )(  ___  )( \    /|\__   __/(  ____ \
 *        | (    )|| (   ) ||  \  ( |   ) (   | (    |/
 *        | (____)|| (___) ||   \ | |   | |   | |
 *        |  _____)|  ___  || (\ \) |   | |   | |
 *        | (      | (   ) || | \   |   | |   | |
 *        | )      | )   ( || )  \  |___) (___| (____|\
 *        |/       |/     \||/    \_)\_______/(_______/
 *
 */

#define _DEFAULT_SOURCE

#include <sys/types.h> // getpwuid

#include <err.h>       // perror
#include <grp.h>       // getgrouplist
#include <libgen.h>    // basename
#include <pwd.h>       // getpwuid
#include <stdio.h>     // printf
#include <stdlib.h>    // exit
#include <unistd.h>    // geteuid

#include <sys/param.h> // NGROUPS_MAX

static const char * __progname;

static void usage(void) {
  printf("Usage: %s [name]\n", __progname);
  exit(EXIT_FAILURE);
}

int main(int argc, char * argv[]) {
  int n = NGROUPS_MAX + 1, i = 0;
  uid_t id;
  gid_t *grs;
  struct passwd *p,*pw;
  struct group *gr;
  __progname = basename(argv[0]);

  if (argc > 2) {
    fprintf(stderr, "%s: too many arguments\n", __progname);
    usage();
  }

  if (argv[1] != NULL) {
    if ((p = getpwnam(argv[1])) == NULL) {
      fprintf(stderr, "%s: unknown user\n", __progname);
      usage();
    }
    id = p->pw_uid;
  } else {
    id = geteuid();
  }

  if ((pw = getpwuid(id)) == NULL) {
    perror("getpwuid");
    exit(EXIT_FAILURE);
  }
  grs = malloc(n * sizeof (gid_t));
  if (getgrouplist(pw->pw_name, pw->pw_gid, grs, &n) == -1) {
    perror("getgrouplist");
    exit(EXIT_FAILURE);
  }
  for (i = 0; i < n; i++) {
    if ((gr = getgrgid(grs[i])) == NULL) {
      perror("getgrid");
      exit(EXIT_FAILURE);
    }
    printf("%s", gr->gr_name);
    if ( i < n-1 )
      putchar(' ');
    else
      putchar('\n');
  }
  return 0;
}
