/*
 * Copyright (c) 2004 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-restart.c,v 1.2 2007/09/29 02:15:44 ca Exp $")

#include "sm/ctype.h"
#include "sm/sysexits.h"
#include "sm/error.h"
#include "sm/signal.h"

#include <stdio.h>

#define PIDFN "t-restart.pid"
#define SLEEPT	60

static int Verbose = 0;

#include "rdwrcounter.c"

static void
usage(char *prg)
{
	fprintf(stderr,
		"usage: %s [options] -f filename\n"
		"options:\n"
		"-n n:       use n as limit [0]\n"
		"-p pidfile: use pidfile for writing pid [%s]\n"
		"-r n:       use exit code n [0]\n"
		"-s n:       sleep n seconds [%d]\n"
		"-V:         increase verbosity\n\n"
		"%s reads a counter from filename and writes back counter + 1\n"
		"if counter is less then the limit then the program exits "
		"immediately\notherwise it will sleep for a while\n"
		, prg, PIDFN, SLEEPT, prg);
	exit(EX_USAGE);
}

int
main(int argc, char *argv[])
{
	int c, cnt, cur, sleept, rc, rconce;
	pid_t pid;
	char *cntfn, *pidfn, *prg;
	FILE *pidfp;

	prg = argv[0];
	cntfn = NULL;
	pidfn = PIDFN;
	pidfp = NULL;
	pid = getpid();
	sleept = SLEEPT;
	rc = cnt = 0;
	rconce = 0;
	while ((c = getopt(argc, argv, "Af:n:p:Rr:s:V")) != -1)
	{
		switch (c)
		{
		  case 'A':
			rc = EX_RESTARTALL;
			rconce = 1;
			break;
		  case 'f':
			cntfn = optarg;
			break;
		  case 'n':
			cnt = atoi(optarg);
			break;
		  case 'p':
			pidfn = optarg;
			break;
		  case 'R':
			rc = EX_RESTARTDEP;
			rconce = 1;
			break;
		  case 'r':
			rc = atoi(optarg);
			break;
		  case 's':
			sleept = atoi(optarg);
			break;
		  case 'V':
			++Verbose;
			break;
		  case 'h':
		  case '?':
		  default:
			usage(prg);
			break;
		}
	}

	if (Verbose > 0)
		fprintf(stderr, "%s: pid=%ld\n", prg, (long) pid);

	/* get current invocation counter */
	if (cntfn == NULL)
	{
		fprintf(stderr, "%s: missing -f filename\n", prg);
		return EX_USAGE;
	}
	c = rdwrcounter(prg, cntfn, &cur);
	if (c != 0)
		return c;

	if (Verbose > 0)
		fprintf(stderr, "%s: pid=%ld, cur=%d\n"
			, prg, (long) pid, cur);

	/* ugly hack: reset to "default" values after first invocation */
	if (rc != 0 && cur > 0 && rconce) {
		rc = 0;
		sleept = SLEEPT;
	}

	/* write pid */
	pidfp = fopen(pidfn, "w");
	if (pidfp == NULL)
	{
		fprintf(stderr, "%s: can't open \"%s\"\n",
			prg, pidfn);
		exit(EX_OSERR);
	}
	fprintf(pidfp, "%ld\n", (long) pid);
	fclose(pidfp);
	pidfp = NULL;

	if (Verbose > 0)
		fprintf(stderr, "%s: pid=%ld, cur=%d, n=%d\n", prg, (long) pid, cur, cnt);

	if (cur >= cnt)
		return 0;

	sleep(sleept);

	if (Verbose > 0)
		fprintf(stderr, "%s: pid=%ld, done=%d\n", prg, (long) pid, rc);

	return rc;
}


syntax highlighted by Code2HTML, v. 0.9.1