convtime.c revision 64562
1/*
2 * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#ifndef lint
15static char id[] = "@(#)$Id: convtime.c,v 8.25 1999/06/16 21:11:26 ca Exp $";
16#endif /* ! lint */
17
18#include <sendmail.h>
19
20/*
21**  CONVTIME -- convert time
22**
23**	Takes a time as an ascii string with a trailing character
24**	giving units:
25**	  s -- seconds
26**	  m -- minutes
27**	  h -- hours
28**	  d -- days (default)
29**	  w -- weeks
30**	For example, "3d12h" is three and a half days.
31**
32**	Parameters:
33**		p -- pointer to ascii time.
34**		units -- default units if none specified.
35**
36**	Returns:
37**		time in seconds.
38**
39**	Side Effects:
40**		none.
41*/
42
43time_t
44convtime(p, units)
45	char *p;
46	int units;
47{
48	register time_t t, r;
49	register char c;
50
51	r = 0;
52	if (strcasecmp(p, "now") == 0)
53		return NOW;
54	while (*p != '\0')
55	{
56		t = 0;
57		while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
58			t = t * 10 + (c - '0');
59		if (c == '\0')
60		{
61			c = units;
62			p--;
63		}
64		else if (strchr("wdhms", c) == NULL)
65		{
66			usrerr("Invalid time unit `%c'", c);
67			c = units;
68		}
69		switch (c)
70		{
71		  case 'w':		/* weeks */
72			t *= 7;
73			/* FALLTHROUGH */
74
75		  case 'd':		/* days */
76			/* FALLTHROUGH */
77		  default:
78			t *= 24;
79			/* FALLTHROUGH */
80
81		  case 'h':		/* hours */
82			t *= 60;
83			/* FALLTHROUGH */
84
85		  case 'm':		/* minutes */
86			t *= 60;
87			/* FALLTHROUGH */
88
89		  case 's':		/* seconds */
90			break;
91		}
92		r += t;
93	}
94
95	return r;
96}
97/*
98**  PINTVL -- produce printable version of a time interval
99**
100**	Parameters:
101**		intvl -- the interval to be converted
102**		brief -- if TRUE, print this in an extremely compact form
103**			(basically used for logging).
104**
105**	Returns:
106**		A pointer to a string version of intvl suitable for
107**			printing or framing.
108**
109**	Side Effects:
110**		none.
111**
112**	Warning:
113**		The string returned is in a static buffer.
114*/
115
116#define PLURAL(n)	((n) == 1 ? "" : "s")
117
118char *
119pintvl(intvl, brief)
120	time_t intvl;
121	bool brief;
122{
123	static char buf[256];
124	register char *p;
125	int wk, dy, hr, mi, se;
126
127	if (intvl == 0 && !brief)
128		return "zero seconds";
129	if (intvl == NOW)
130		return "too long";
131
132	/* decode the interval into weeks, days, hours, minutes, seconds */
133	se = intvl % 60;
134	intvl /= 60;
135	mi = intvl % 60;
136	intvl /= 60;
137	hr = intvl % 24;
138	intvl /= 24;
139	if (brief)
140	{
141		dy = intvl;
142		wk = 0;
143	}
144	else
145	{
146		dy = intvl % 7;
147		intvl /= 7;
148		wk = intvl;
149	}
150
151	/* now turn it into a sexy form */
152	p = buf;
153	if (brief)
154	{
155		if (dy > 0)
156		{
157			(void) snprintf(p, SPACELEFT(buf, p), "%d+", dy);
158			p += strlen(p);
159		}
160		(void) snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
161			hr, mi, se);
162		return buf;
163	}
164
165	/* use the verbose form */
166	if (wk > 0)
167	{
168		(void) snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk, PLURAL(wk));
169		p += strlen(p);
170	}
171	if (dy > 0)
172	{
173		(void) snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy, PLURAL(dy));
174		p += strlen(p);
175	}
176	if (hr > 0)
177	{
178		(void) snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr, PLURAL(hr));
179		p += strlen(p);
180	}
181	if (mi > 0)
182	{
183		(void) snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi, PLURAL(mi));
184		p += strlen(p);
185	}
186	if (se > 0)
187	{
188		(void) snprintf(p, SPACELEFT(buf, p), ", %d second%s", se, PLURAL(se));
189		p += strlen(p);
190	}
191
192	return (buf + 2);
193}
194