17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
37c478bdstevel@tonic-gate *	All rights reserved.
47c478bdstevel@tonic-gate * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
57c478bdstevel@tonic-gate * Copyright (c) 1988, 1993
67c478bdstevel@tonic-gate *	The Regents of the University of California.  All rights reserved.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * By using this file, you agree to the terms and conditions set
97c478bdstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of
107c478bdstevel@tonic-gate * the sendmail distribution.
117c478bdstevel@tonic-gate *
127c478bdstevel@tonic-gate */
137c478bdstevel@tonic-gate
147c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
157c478bdstevel@tonic-gate
167c478bdstevel@tonic-gate#include <sendmail.h>
177c478bdstevel@tonic-gate
187c478bdstevel@tonic-gateSM_RCSID("@(#)$Id: convtime.c,v 8.36 2001/02/13 22:32:08 ca Exp $")
197c478bdstevel@tonic-gate
207c478bdstevel@tonic-gate/*
217c478bdstevel@tonic-gate**  CONVTIME -- convert time
227c478bdstevel@tonic-gate**
237c478bdstevel@tonic-gate**	Takes a time as an ascii string with a trailing character
247c478bdstevel@tonic-gate**	giving units:
257c478bdstevel@tonic-gate**	  s -- seconds
267c478bdstevel@tonic-gate**	  m -- minutes
277c478bdstevel@tonic-gate**	  h -- hours
287c478bdstevel@tonic-gate**	  d -- days (default)
297c478bdstevel@tonic-gate**	  w -- weeks
307c478bdstevel@tonic-gate**	For example, "3d12h" is three and a half days.
317c478bdstevel@tonic-gate**
327c478bdstevel@tonic-gate**	Parameters:
337c478bdstevel@tonic-gate**		p -- pointer to ascii time.
347c478bdstevel@tonic-gate**		units -- default units if none specified.
357c478bdstevel@tonic-gate**
367c478bdstevel@tonic-gate**	Returns:
377c478bdstevel@tonic-gate**		time in seconds.
387c478bdstevel@tonic-gate**
397c478bdstevel@tonic-gate**	Side Effects:
407c478bdstevel@tonic-gate**		none.
417c478bdstevel@tonic-gate*/
427c478bdstevel@tonic-gate
437c478bdstevel@tonic-gatetime_t
447c478bdstevel@tonic-gateconvtime(p, units)
457c478bdstevel@tonic-gate	char *p;
467c478bdstevel@tonic-gate	int units;
477c478bdstevel@tonic-gate{
487c478bdstevel@tonic-gate	register time_t t, r;
497c478bdstevel@tonic-gate	register char c;
507c478bdstevel@tonic-gate	bool pos = true;
517c478bdstevel@tonic-gate
527c478bdstevel@tonic-gate	r = 0;
537c478bdstevel@tonic-gate	if (sm_strcasecmp(p, "now") == 0)
547c478bdstevel@tonic-gate		return NOW;
557c478bdstevel@tonic-gate	if (*p == '-')
567c478bdstevel@tonic-gate	{
577c478bdstevel@tonic-gate		pos = false;
587c478bdstevel@tonic-gate		++p;
597c478bdstevel@tonic-gate	}
607c478bdstevel@tonic-gate	while (*p != '\0')
617c478bdstevel@tonic-gate	{
627c478bdstevel@tonic-gate		t = 0;
637c478bdstevel@tonic-gate		while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
647c478bdstevel@tonic-gate			t = t * 10 + (c - '0');
657c478bdstevel@tonic-gate		if (c == '\0')
667c478bdstevel@tonic-gate		{
677c478bdstevel@tonic-gate			c = units;
687c478bdstevel@tonic-gate			p--;
697c478bdstevel@tonic-gate		}
707c478bdstevel@tonic-gate		else if (strchr("wdhms", c) == NULL)
717c478bdstevel@tonic-gate		{
727c478bdstevel@tonic-gate			usrerr("Invalid time unit `%c'", c);
737c478bdstevel@tonic-gate			c = units;
747c478bdstevel@tonic-gate		}
757c478bdstevel@tonic-gate		switch (c)
767c478bdstevel@tonic-gate		{
777c478bdstevel@tonic-gate		  case 'w':		/* weeks */
787c478bdstevel@tonic-gate			t *= 7;
797c478bdstevel@tonic-gate			/* FALLTHROUGH */
807c478bdstevel@tonic-gate
817c478bdstevel@tonic-gate		  case 'd':		/* days */
827c478bdstevel@tonic-gate			/* FALLTHROUGH */
837c478bdstevel@tonic-gate		  default:
847c478bdstevel@tonic-gate			t *= 24;
857c478bdstevel@tonic-gate			/* FALLTHROUGH */
867c478bdstevel@tonic-gate
877c478bdstevel@tonic-gate		  case 'h':		/* hours */
887c478bdstevel@tonic-gate			t *= 60;
897c478bdstevel@tonic-gate			/* FALLTHROUGH */
907c478bdstevel@tonic-gate
917c478bdstevel@tonic-gate		  case 'm':		/* minutes */
927c478bdstevel@tonic-gate			t *= 60;
937c478bdstevel@tonic-gate			/* FALLTHROUGH */
947c478bdstevel@tonic-gate
957c478bdstevel@tonic-gate		  case 's':		/* seconds */
967c478bdstevel@tonic-gate			break;
977c478bdstevel@tonic-gate		}
987c478bdstevel@tonic-gate		r += t;
997c478bdstevel@tonic-gate	}
1007c478bdstevel@tonic-gate
1017c478bdstevel@tonic-gate	return pos ? r : -r;
1027c478bdstevel@tonic-gate}
1037c478bdstevel@tonic-gate/*
1047c478bdstevel@tonic-gate**  PINTVL -- produce printable version of a time interval
1057c478bdstevel@tonic-gate**
1067c478bdstevel@tonic-gate**	Parameters:
1077c478bdstevel@tonic-gate**		intvl -- the interval to be converted
1087c478bdstevel@tonic-gate**		brief -- if true, print this in an extremely compact form
1097c478bdstevel@tonic-gate**			(basically used for logging).
1107c478bdstevel@tonic-gate**
1117c478bdstevel@tonic-gate**	Returns:
1127c478bdstevel@tonic-gate**		A pointer to a string version of intvl suitable for
1137c478bdstevel@tonic-gate**			printing or framing.
1147c478bdstevel@tonic-gate**
1157c478bdstevel@tonic-gate**	Side Effects:
1167c478bdstevel@tonic-gate**		none.
1177c478bdstevel@tonic-gate**
1187c478bdstevel@tonic-gate**	Warning:
1197c478bdstevel@tonic-gate**		The string returned is in a static buffer.
1207c478bdstevel@tonic-gate*/
1217c478bdstevel@tonic-gate
1227c478bdstevel@tonic-gate#define PLURAL(n)	((n) == 1 ? "" : "s")
1237c478bdstevel@tonic-gate
1247c478bdstevel@tonic-gatechar *
1257c478bdstevel@tonic-gatepintvl(intvl, brief)
1267c478bdstevel@tonic-gate	time_t intvl;
1277c478bdstevel@tonic-gate	bool brief;
1287c478bdstevel@tonic-gate{
1297c478bdstevel@tonic-gate	static char buf[256];
1307c478bdstevel@tonic-gate	register char *p;
1317c478bdstevel@tonic-gate	int wk, dy, hr, mi, se;
1327c478bdstevel@tonic-gate
1337c478bdstevel@tonic-gate	if (intvl == 0 && !brief)
1347c478bdstevel@tonic-gate		return "zero seconds";
1357c478bdstevel@tonic-gate	if (intvl == NOW)
1367c478bdstevel@tonic-gate		return "too long";
1377c478bdstevel@tonic-gate
1387c478bdstevel@tonic-gate	/* decode the interval into weeks, days, hours, minutes, seconds */
1397c478bdstevel@tonic-gate	se = intvl % 60;
1407c478bdstevel@tonic-gate	intvl /= 60;
1417c478bdstevel@tonic-gate	mi = intvl % 60;
1427c478bdstevel@tonic-gate	intvl /= 60;
1437c478bdstevel@tonic-gate	hr = intvl % 24;
1447c478bdstevel@tonic-gate	intvl /= 24;
1457c478bdstevel@tonic-gate	if (brief)
1467c478bdstevel@tonic-gate	{
1477c478bdstevel@tonic-gate		dy = intvl;
1487c478bdstevel@tonic-gate		wk = 0;
1497c478bdstevel@tonic-gate	}
1507c478bdstevel@tonic-gate	else
1517c478bdstevel@tonic-gate	{
1527c478bdstevel@tonic-gate		dy = intvl % 7;
1537c478bdstevel@tonic-gate		intvl /= 7;
1547c478bdstevel@tonic-gate		wk = intvl;
1557c478bdstevel@tonic-gate	}
1567c478bdstevel@tonic-gate
1577c478bdstevel@tonic-gate	/* now turn it into a sexy form */
1587c478bdstevel@tonic-gate	p = buf;
1597c478bdstevel@tonic-gate	if (brief)
1607c478bdstevel@tonic-gate	{
1617c478bdstevel@tonic-gate		if (dy > 0)
1627c478bdstevel@tonic-gate		{
1637c478bdstevel@tonic-gate			(void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy);
1647c478bdstevel@tonic-gate			p += strlen(p);
1657c478bdstevel@tonic-gate		}
1667c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
1677c478bdstevel@tonic-gate				   hr, mi, se);
1687c478bdstevel@tonic-gate		return buf;
1697c478bdstevel@tonic-gate	}
1707c478bdstevel@tonic-gate
1717c478bdstevel@tonic-gate	/* use the verbose form */
1727c478bdstevel@tonic-gate	if (wk > 0)
1737c478bdstevel@tonic-gate	{
1747c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk,
1757c478bdstevel@tonic-gate				   PLURAL(wk));
1767c478bdstevel@tonic-gate		p += strlen(p);
1777c478bdstevel@tonic-gate	}
1787c478bdstevel@tonic-gate	if (dy > 0)
1797c478bdstevel@tonic-gate	{
1807c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy,
1817c478bdstevel@tonic-gate				   PLURAL(dy));
1827c478bdstevel@tonic-gate		p += strlen(p);
1837c478bdstevel@tonic-gate	}
1847c478bdstevel@tonic-gate	if (hr > 0)
1857c478bdstevel@tonic-gate	{
1867c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr,
1877c478bdstevel@tonic-gate				   PLURAL(hr));
1887c478bdstevel@tonic-gate		p += strlen(p);
1897c478bdstevel@tonic-gate	}
1907c478bdstevel@tonic-gate	if (mi > 0)
1917c478bdstevel@tonic-gate	{
1927c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi,
1937c478bdstevel@tonic-gate				   PLURAL(mi));
1947c478bdstevel@tonic-gate		p += strlen(p);
1957c478bdstevel@tonic-gate	}
1967c478bdstevel@tonic-gate	if (se > 0)
1977c478bdstevel@tonic-gate	{
1987c478bdstevel@tonic-gate		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se,
1997c478bdstevel@tonic-gate				   PLURAL(se));
2007c478bdstevel@tonic-gate		p += strlen(p);
2017c478bdstevel@tonic-gate	}
2027c478bdstevel@tonic-gate
2037c478bdstevel@tonic-gate	return (buf + 2);
2047c478bdstevel@tonic-gate}
205