/*
 * grpunconv - update /etc/group with information from /etc/gshadow.
 *
 * Copyright (C) 1996, Michael Meskes <meskes@debian.org>
 * using sources from Marek Michalkiewicz
 * <marekm@i17linuxb.ists.pwr.wroc.pl>
 * This program may be freely used and distributed.  If you improve
 * it, please send me your changes.  Thanks!
 */

#include <config.h>

#include <stdio.h>

#ifdef SHADOWGRP

#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>

#include <grp.h>
#include "prototypes.h"
#include "groupio.h"
#include "sgroupio.h"

static int group_locked = 0;
static int gshadow_locked = 0;

/* local function prototypes */
static void fail_exit P_((int));
int main P_((int, char **));

static void
fail_exit(int status)
{
	if (group_locked)
		gr_unlock();
	if (gshadow_locked)
		sgr_unlock();
	exit(status);
}

int
main(int argc, char **argv)
{
	const struct group *gr;
	struct group grent;
	const struct sgrp *sg;
	char *Prog = argv[0];

	if (!sgr_file_present())
		exit(0);  /* no /etc/gshadow, nothing to do */

	if (!gr_lock()) {
		fprintf(stderr, "%s: can't lock group file\n", Prog);
		fail_exit(5);
	}
	group_locked++;
	if (!gr_open(O_RDWR)) {
		fprintf(stderr, "%s: can't open group file\n", Prog);
		fail_exit(1);
	}

	if (!sgr_lock()) {
		fprintf(stderr, "%s: can't lock shadow group file\n", Prog);
		fail_exit(5);
	}
	gshadow_locked++;
	if (!sgr_open(O_RDWR)) {
		fprintf(stderr, "%s: can't open shadow group file\n", Prog);
		fail_exit(1);
	}

	/*
	 * Update group passwords if non-shadow password is "x".
	 */
	gr_rewind();
	while ((gr = gr_next())) {
		sg = sgr_locate(gr->gr_name);
		if (sg && strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0) {
	  		/* add password to /etc/group */
	  		grent = *gr;
			grent.gr_passwd = sg->sg_passwd;
			if (!gr_update(&grent)) {
				fprintf(stderr,
					"%s: can't update entry for group %s\n",
					Prog, grent.gr_name);
				fail_exit(3);
			}
		}
	}

	if (!sgr_close()) {
		fprintf(stderr, "%s: can't update shadow group file\n", Prog);
		fail_exit(3);
	}

	if (!gr_close()) {
		fprintf(stderr, "%s: can't update group file\n", Prog);
		fail_exit(3);
	}

	if (unlink(SGROUP_FILE) != 0) {
		fprintf(stderr, "%s: can't delete shadow group file\n", Prog);
		fail_exit(3);
	}

	sgr_unlock();
	gr_unlock();
	return 0;
}
#else
int
main(int argc, char **argv)
{
	fprintf(stderr, "%s: not configured for shadow group support.\n",argv[0]);
	exit(1);
}
#endif
