138032Speter/*
2261370Sgshapiro * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.
364562Sgshapiro *	All rights reserved.
438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
538032Speter * Copyright (c) 1988, 1993
638032Speter *	The Regents of the University of California.  All rights reserved.
738032Speter *
838032Speter * By using this file, you agree to the terms and conditions set
938032Speter * forth in the LICENSE file which can be found at the top level of
1038032Speter * the sendmail distribution.
1138032Speter *
1238032Speter */
1338032Speter
1464562Sgshapiro#include <sendmail.h>
1538032Speter
16266711SgshapiroSM_RCSID("@(#)$Id: convtime.c,v 8.40 2013-11-22 20:51:55 ca Exp $")
1790792Sgshapiro
1838032Speter/*
1938032Speter**  CONVTIME -- convert time
2038032Speter**
2138032Speter**	Takes a time as an ascii string with a trailing character
2238032Speter**	giving units:
2338032Speter**	  s -- seconds
2438032Speter**	  m -- minutes
2538032Speter**	  h -- hours
2638032Speter**	  d -- days (default)
2738032Speter**	  w -- weeks
2838032Speter**	For example, "3d12h" is three and a half days.
2938032Speter**
3038032Speter**	Parameters:
3138032Speter**		p -- pointer to ascii time.
3238032Speter**		units -- default units if none specified.
3338032Speter**
3438032Speter**	Returns:
3538032Speter**		time in seconds.
3638032Speter**
3738032Speter**	Side Effects:
3838032Speter**		none.
3938032Speter*/
4038032Speter
4138032Spetertime_t
4238032Speterconvtime(p, units)
4338032Speter	char *p;
4464562Sgshapiro	int units;
4538032Speter{
4638032Speter	register time_t t, r;
4738032Speter	register char c;
4890792Sgshapiro	bool pos = true;
4938032Speter
5038032Speter	r = 0;
5190792Sgshapiro	if (sm_strcasecmp(p, "now") == 0)
5264562Sgshapiro		return NOW;
5390792Sgshapiro	if (*p == '-')
5490792Sgshapiro	{
5590792Sgshapiro		pos = false;
5690792Sgshapiro		++p;
5790792Sgshapiro	}
5838032Speter	while (*p != '\0')
5938032Speter	{
6038032Speter		t = 0;
6138032Speter		while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
6238032Speter			t = t * 10 + (c - '0');
6338032Speter		if (c == '\0')
6438032Speter		{
6538032Speter			c = units;
6638032Speter			p--;
6738032Speter		}
6838032Speter		else if (strchr("wdhms", c) == NULL)
6938032Speter		{
7038032Speter			usrerr("Invalid time unit `%c'", c);
7138032Speter			c = units;
7238032Speter		}
7338032Speter		switch (c)
7438032Speter		{
7538032Speter		  case 'w':		/* weeks */
7638032Speter			t *= 7;
7764562Sgshapiro			/* FALLTHROUGH */
7838032Speter
7938032Speter		  case 'd':		/* days */
8064562Sgshapiro			/* FALLTHROUGH */
8138032Speter		  default:
8238032Speter			t *= 24;
8364562Sgshapiro			/* FALLTHROUGH */
8438032Speter
8538032Speter		  case 'h':		/* hours */
8638032Speter			t *= 60;
8764562Sgshapiro			/* FALLTHROUGH */
8838032Speter
8938032Speter		  case 'm':		/* minutes */
9038032Speter			t *= 60;
9164562Sgshapiro			/* FALLTHROUGH */
9238032Speter
9338032Speter		  case 's':		/* seconds */
9438032Speter			break;
9538032Speter		}
9638032Speter		r += t;
9738032Speter	}
9838032Speter
9990792Sgshapiro	return pos ? r : -r;
10038032Speter}
10190792Sgshapiro/*
10238032Speter**  PINTVL -- produce printable version of a time interval
10338032Speter**
10438032Speter**	Parameters:
10538032Speter**		intvl -- the interval to be converted
10690792Sgshapiro**		brief -- if true, print this in an extremely compact form
10738032Speter**			(basically used for logging).
10838032Speter**
10938032Speter**	Returns:
11038032Speter**		A pointer to a string version of intvl suitable for
11138032Speter**			printing or framing.
11238032Speter**
11338032Speter**	Side Effects:
11438032Speter**		none.
11538032Speter**
11638032Speter**	Warning:
11738032Speter**		The string returned is in a static buffer.
11838032Speter*/
11938032Speter
12064562Sgshapiro#define PLURAL(n)	((n) == 1 ? "" : "s")
12138032Speter
12238032Speterchar *
12338032Speterpintvl(intvl, brief)
12438032Speter	time_t intvl;
12538032Speter	bool brief;
12638032Speter{
12738032Speter	static char buf[256];
12838032Speter	register char *p;
12938032Speter	int wk, dy, hr, mi, se;
13038032Speter
13138032Speter	if (intvl == 0 && !brief)
13264562Sgshapiro		return "zero seconds";
13364562Sgshapiro	if (intvl == NOW)
13464562Sgshapiro		return "too long";
13538032Speter
13638032Speter	/* decode the interval into weeks, days, hours, minutes, seconds */
13738032Speter	se = intvl % 60;
13838032Speter	intvl /= 60;
13938032Speter	mi = intvl % 60;
14038032Speter	intvl /= 60;
14138032Speter	hr = intvl % 24;
14238032Speter	intvl /= 24;
14338032Speter	if (brief)
14438032Speter	{
14538032Speter		dy = intvl;
14638032Speter		wk = 0;
14738032Speter	}
14838032Speter	else
14938032Speter	{
15038032Speter		dy = intvl % 7;
15138032Speter		intvl /= 7;
15238032Speter		wk = intvl;
15338032Speter	}
15438032Speter
15538032Speter	/* now turn it into a sexy form */
15638032Speter	p = buf;
15738032Speter	if (brief)
15838032Speter	{
15938032Speter		if (dy > 0)
16038032Speter		{
16190792Sgshapiro			(void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy);
16238032Speter			p += strlen(p);
16338032Speter		}
16490792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
16590792Sgshapiro				   hr, mi, se);
16664562Sgshapiro		return buf;
16738032Speter	}
16838032Speter
16938032Speter	/* use the verbose form */
17038032Speter	if (wk > 0)
17138032Speter	{
17290792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk,
17390792Sgshapiro				   PLURAL(wk));
17438032Speter		p += strlen(p);
17538032Speter	}
17638032Speter	if (dy > 0)
17738032Speter	{
17890792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy,
17990792Sgshapiro				   PLURAL(dy));
18038032Speter		p += strlen(p);
18138032Speter	}
18238032Speter	if (hr > 0)
18338032Speter	{
18490792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr,
18590792Sgshapiro				   PLURAL(hr));
18638032Speter		p += strlen(p);
18738032Speter	}
18838032Speter	if (mi > 0)
18938032Speter	{
19090792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi,
19190792Sgshapiro				   PLURAL(mi));
19238032Speter		p += strlen(p);
19338032Speter	}
19438032Speter	if (se > 0)
19538032Speter	{
19690792Sgshapiro		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se,
19790792Sgshapiro				   PLURAL(se));
19838032Speter		p += strlen(p);
19938032Speter	}
20038032Speter
20138032Speter	return (buf + 2);
20238032Speter}
203