xref: /freebsd/contrib/sendmail/src/convtime.c (revision 2fb4f839f3fc72ce2bab12f9ba4760f97f73e97f)
1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
1406f25ae9SGregory Neil Shapiro #include <sendmail.h>
15c2aa98e2SPeter Wemm 
164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: convtime.c,v 8.40 2013-11-22 20:51:55 ca Exp $")
17*2fb4f839SGregory Neil Shapiro #include <sm/sendmail.h>
1840266059SGregory Neil Shapiro 
19c2aa98e2SPeter Wemm /*
20c2aa98e2SPeter Wemm **  CONVTIME -- convert time
21c2aa98e2SPeter Wemm **
22c2aa98e2SPeter Wemm **	Takes a time as an ascii string with a trailing character
23c2aa98e2SPeter Wemm **	giving units:
24c2aa98e2SPeter Wemm **	  s -- seconds
25c2aa98e2SPeter Wemm **	  m -- minutes
26c2aa98e2SPeter Wemm **	  h -- hours
27c2aa98e2SPeter Wemm **	  d -- days (default)
28c2aa98e2SPeter Wemm **	  w -- weeks
29c2aa98e2SPeter Wemm **	For example, "3d12h" is three and a half days.
30c2aa98e2SPeter Wemm **
31c2aa98e2SPeter Wemm **	Parameters:
32c2aa98e2SPeter Wemm **		p -- pointer to ascii time.
33c2aa98e2SPeter Wemm **		units -- default units if none specified.
34c2aa98e2SPeter Wemm **
35c2aa98e2SPeter Wemm **	Returns:
36c2aa98e2SPeter Wemm **		time in seconds.
37c2aa98e2SPeter Wemm **
38c2aa98e2SPeter Wemm **	Side Effects:
39c2aa98e2SPeter Wemm **		none.
40c2aa98e2SPeter Wemm */
41c2aa98e2SPeter Wemm 
42c2aa98e2SPeter Wemm time_t
43c2aa98e2SPeter Wemm convtime(p, units)
44c2aa98e2SPeter Wemm 	char *p;
4506f25ae9SGregory Neil Shapiro 	int units;
46c2aa98e2SPeter Wemm {
47c2aa98e2SPeter Wemm 	register time_t t, r;
48c2aa98e2SPeter Wemm 	register char c;
4940266059SGregory Neil Shapiro 	bool pos = true;
50c2aa98e2SPeter Wemm 
51c2aa98e2SPeter Wemm 	r = 0;
52*2fb4f839SGregory Neil Shapiro 	if (SM_STRCASEEQ(p, "now"))
5306f25ae9SGregory Neil Shapiro 		return NOW;
5440266059SGregory Neil Shapiro 	if (*p == '-')
5540266059SGregory Neil Shapiro 	{
5640266059SGregory Neil Shapiro 		pos = false;
5740266059SGregory Neil Shapiro 		++p;
5840266059SGregory Neil Shapiro 	}
59c2aa98e2SPeter Wemm 	while (*p != '\0')
60c2aa98e2SPeter Wemm 	{
61c2aa98e2SPeter Wemm 		t = 0;
62c2aa98e2SPeter Wemm 		while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
63c2aa98e2SPeter Wemm 			t = t * 10 + (c - '0');
64c2aa98e2SPeter Wemm 		if (c == '\0')
65c2aa98e2SPeter Wemm 		{
66c2aa98e2SPeter Wemm 			c = units;
67c2aa98e2SPeter Wemm 			p--;
68c2aa98e2SPeter Wemm 		}
69c2aa98e2SPeter Wemm 		else if (strchr("wdhms", c) == NULL)
70c2aa98e2SPeter Wemm 		{
71c2aa98e2SPeter Wemm 			usrerr("Invalid time unit `%c'", c);
72c2aa98e2SPeter Wemm 			c = units;
73c2aa98e2SPeter Wemm 		}
74c2aa98e2SPeter Wemm 		switch (c)
75c2aa98e2SPeter Wemm 		{
76c2aa98e2SPeter Wemm 		  case 'w':		/* weeks */
77c2aa98e2SPeter Wemm 			t *= 7;
7806f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
79c2aa98e2SPeter Wemm 
80c2aa98e2SPeter Wemm 		  case 'd':		/* days */
8106f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
82c2aa98e2SPeter Wemm 		  default:
83c2aa98e2SPeter Wemm 			t *= 24;
8406f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
85c2aa98e2SPeter Wemm 
86c2aa98e2SPeter Wemm 		  case 'h':		/* hours */
87c2aa98e2SPeter Wemm 			t *= 60;
8806f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
89c2aa98e2SPeter Wemm 
90c2aa98e2SPeter Wemm 		  case 'm':		/* minutes */
91c2aa98e2SPeter Wemm 			t *= 60;
9206f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
93c2aa98e2SPeter Wemm 
94c2aa98e2SPeter Wemm 		  case 's':		/* seconds */
95c2aa98e2SPeter Wemm 			break;
96c2aa98e2SPeter Wemm 		}
97c2aa98e2SPeter Wemm 		r += t;
98c2aa98e2SPeter Wemm 	}
99c2aa98e2SPeter Wemm 
10040266059SGregory Neil Shapiro 	return pos ? r : -r;
101c2aa98e2SPeter Wemm }
10240266059SGregory Neil Shapiro /*
103c2aa98e2SPeter Wemm **  PINTVL -- produce printable version of a time interval
104c2aa98e2SPeter Wemm **
105c2aa98e2SPeter Wemm **	Parameters:
106c2aa98e2SPeter Wemm **		intvl -- the interval to be converted
10740266059SGregory Neil Shapiro **		brief -- if true, print this in an extremely compact form
108c2aa98e2SPeter Wemm **			(basically used for logging).
109c2aa98e2SPeter Wemm **
110c2aa98e2SPeter Wemm **	Returns:
111c2aa98e2SPeter Wemm **		A pointer to a string version of intvl suitable for
112c2aa98e2SPeter Wemm **			printing or framing.
113c2aa98e2SPeter Wemm **
114c2aa98e2SPeter Wemm **	Side Effects:
115c2aa98e2SPeter Wemm **		none.
116c2aa98e2SPeter Wemm **
117c2aa98e2SPeter Wemm **	Warning:
118c2aa98e2SPeter Wemm **		The string returned is in a static buffer.
119c2aa98e2SPeter Wemm */
120c2aa98e2SPeter Wemm 
121c2aa98e2SPeter Wemm #define PLURAL(n)	((n) == 1 ? "" : "s")
122c2aa98e2SPeter Wemm 
123c2aa98e2SPeter Wemm char *
pintvl(intvl,brief)124c2aa98e2SPeter Wemm pintvl(intvl, brief)
125c2aa98e2SPeter Wemm 	time_t intvl;
126c2aa98e2SPeter Wemm 	bool brief;
127c2aa98e2SPeter Wemm {
128c2aa98e2SPeter Wemm 	static char buf[256];
129c2aa98e2SPeter Wemm 	register char *p;
130c2aa98e2SPeter Wemm 	int wk, dy, hr, mi, se;
131c2aa98e2SPeter Wemm 
132c2aa98e2SPeter Wemm 	if (intvl == 0 && !brief)
13306f25ae9SGregory Neil Shapiro 		return "zero seconds";
13406f25ae9SGregory Neil Shapiro 	if (intvl == NOW)
13506f25ae9SGregory Neil Shapiro 		return "too long";
136c2aa98e2SPeter Wemm 
137c2aa98e2SPeter Wemm 	/* decode the interval into weeks, days, hours, minutes, seconds */
138c2aa98e2SPeter Wemm 	se = intvl % 60;
139c2aa98e2SPeter Wemm 	intvl /= 60;
140c2aa98e2SPeter Wemm 	mi = intvl % 60;
141c2aa98e2SPeter Wemm 	intvl /= 60;
142c2aa98e2SPeter Wemm 	hr = intvl % 24;
143c2aa98e2SPeter Wemm 	intvl /= 24;
144c2aa98e2SPeter Wemm 	if (brief)
145c2aa98e2SPeter Wemm 	{
146c2aa98e2SPeter Wemm 		dy = intvl;
147c2aa98e2SPeter Wemm 		wk = 0;
148c2aa98e2SPeter Wemm 	}
149c2aa98e2SPeter Wemm 	else
150c2aa98e2SPeter Wemm 	{
151c2aa98e2SPeter Wemm 		dy = intvl % 7;
152c2aa98e2SPeter Wemm 		intvl /= 7;
153c2aa98e2SPeter Wemm 		wk = intvl;
154c2aa98e2SPeter Wemm 	}
155c2aa98e2SPeter Wemm 
156c2aa98e2SPeter Wemm 	/* now turn it into a sexy form */
157c2aa98e2SPeter Wemm 	p = buf;
158c2aa98e2SPeter Wemm 	if (brief)
159c2aa98e2SPeter Wemm 	{
160c2aa98e2SPeter Wemm 		if (dy > 0)
161c2aa98e2SPeter Wemm 		{
16240266059SGregory Neil Shapiro 			(void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy);
163c2aa98e2SPeter Wemm 			p += strlen(p);
164c2aa98e2SPeter Wemm 		}
16540266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
166c2aa98e2SPeter Wemm 				   hr, mi, se);
16706f25ae9SGregory Neil Shapiro 		return buf;
168c2aa98e2SPeter Wemm 	}
169c2aa98e2SPeter Wemm 
170c2aa98e2SPeter Wemm 	/* use the verbose form */
171c2aa98e2SPeter Wemm 	if (wk > 0)
172c2aa98e2SPeter Wemm 	{
17340266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk,
17440266059SGregory Neil Shapiro 				   PLURAL(wk));
175c2aa98e2SPeter Wemm 		p += strlen(p);
176c2aa98e2SPeter Wemm 	}
177c2aa98e2SPeter Wemm 	if (dy > 0)
178c2aa98e2SPeter Wemm 	{
17940266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy,
18040266059SGregory Neil Shapiro 				   PLURAL(dy));
181c2aa98e2SPeter Wemm 		p += strlen(p);
182c2aa98e2SPeter Wemm 	}
183c2aa98e2SPeter Wemm 	if (hr > 0)
184c2aa98e2SPeter Wemm 	{
18540266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr,
18640266059SGregory Neil Shapiro 				   PLURAL(hr));
187c2aa98e2SPeter Wemm 		p += strlen(p);
188c2aa98e2SPeter Wemm 	}
189c2aa98e2SPeter Wemm 	if (mi > 0)
190c2aa98e2SPeter Wemm 	{
19140266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi,
19240266059SGregory Neil Shapiro 				   PLURAL(mi));
193c2aa98e2SPeter Wemm 		p += strlen(p);
194c2aa98e2SPeter Wemm 	}
195c2aa98e2SPeter Wemm 	if (se > 0)
196c2aa98e2SPeter Wemm 	{
19740266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se,
19840266059SGregory Neil Shapiro 				   PLURAL(se));
199c2aa98e2SPeter Wemm 		p += strlen(p);
200c2aa98e2SPeter Wemm 	}
201c2aa98e2SPeter Wemm 
202c2aa98e2SPeter Wemm 	return (buf + 2);
203c2aa98e2SPeter Wemm }
204