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