xref: /freebsd/contrib/sendmail/src/convtime.c (revision 4313cc83440a39bdf976f955b1d4d3f3c4d1552f)
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 
16*4313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: convtime.c,v 8.40 2013-11-22 20:51:55 ca Exp $")
1740266059SGregory Neil Shapiro 
18c2aa98e2SPeter Wemm /*
19c2aa98e2SPeter Wemm **  CONVTIME -- convert time
20c2aa98e2SPeter Wemm **
21c2aa98e2SPeter Wemm **	Takes a time as an ascii string with a trailing character
22c2aa98e2SPeter Wemm **	giving units:
23c2aa98e2SPeter Wemm **	  s -- seconds
24c2aa98e2SPeter Wemm **	  m -- minutes
25c2aa98e2SPeter Wemm **	  h -- hours
26c2aa98e2SPeter Wemm **	  d -- days (default)
27c2aa98e2SPeter Wemm **	  w -- weeks
28c2aa98e2SPeter Wemm **	For example, "3d12h" is three and a half days.
29c2aa98e2SPeter Wemm **
30c2aa98e2SPeter Wemm **	Parameters:
31c2aa98e2SPeter Wemm **		p -- pointer to ascii time.
32c2aa98e2SPeter Wemm **		units -- default units if none specified.
33c2aa98e2SPeter Wemm **
34c2aa98e2SPeter Wemm **	Returns:
35c2aa98e2SPeter Wemm **		time in seconds.
36c2aa98e2SPeter Wemm **
37c2aa98e2SPeter Wemm **	Side Effects:
38c2aa98e2SPeter Wemm **		none.
39c2aa98e2SPeter Wemm */
40c2aa98e2SPeter Wemm 
41c2aa98e2SPeter Wemm time_t
42c2aa98e2SPeter Wemm convtime(p, units)
43c2aa98e2SPeter Wemm 	char *p;
4406f25ae9SGregory Neil Shapiro 	int units;
45c2aa98e2SPeter Wemm {
46c2aa98e2SPeter Wemm 	register time_t t, r;
47c2aa98e2SPeter Wemm 	register char c;
4840266059SGregory Neil Shapiro 	bool pos = true;
49c2aa98e2SPeter Wemm 
50c2aa98e2SPeter Wemm 	r = 0;
5140266059SGregory Neil Shapiro 	if (sm_strcasecmp(p, "now") == 0)
5206f25ae9SGregory Neil Shapiro 		return NOW;
5340266059SGregory Neil Shapiro 	if (*p == '-')
5440266059SGregory Neil Shapiro 	{
5540266059SGregory Neil Shapiro 		pos = false;
5640266059SGregory Neil Shapiro 		++p;
5740266059SGregory Neil Shapiro 	}
58c2aa98e2SPeter Wemm 	while (*p != '\0')
59c2aa98e2SPeter Wemm 	{
60c2aa98e2SPeter Wemm 		t = 0;
61c2aa98e2SPeter Wemm 		while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
62c2aa98e2SPeter Wemm 			t = t * 10 + (c - '0');
63c2aa98e2SPeter Wemm 		if (c == '\0')
64c2aa98e2SPeter Wemm 		{
65c2aa98e2SPeter Wemm 			c = units;
66c2aa98e2SPeter Wemm 			p--;
67c2aa98e2SPeter Wemm 		}
68c2aa98e2SPeter Wemm 		else if (strchr("wdhms", c) == NULL)
69c2aa98e2SPeter Wemm 		{
70c2aa98e2SPeter Wemm 			usrerr("Invalid time unit `%c'", c);
71c2aa98e2SPeter Wemm 			c = units;
72c2aa98e2SPeter Wemm 		}
73c2aa98e2SPeter Wemm 		switch (c)
74c2aa98e2SPeter Wemm 		{
75c2aa98e2SPeter Wemm 		  case 'w':		/* weeks */
76c2aa98e2SPeter Wemm 			t *= 7;
7706f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
78c2aa98e2SPeter Wemm 
79c2aa98e2SPeter Wemm 		  case 'd':		/* days */
8006f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
81c2aa98e2SPeter Wemm 		  default:
82c2aa98e2SPeter Wemm 			t *= 24;
8306f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
84c2aa98e2SPeter Wemm 
85c2aa98e2SPeter Wemm 		  case 'h':		/* hours */
86c2aa98e2SPeter Wemm 			t *= 60;
8706f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
88c2aa98e2SPeter Wemm 
89c2aa98e2SPeter Wemm 		  case 'm':		/* minutes */
90c2aa98e2SPeter Wemm 			t *= 60;
9106f25ae9SGregory Neil Shapiro 			/* FALLTHROUGH */
92c2aa98e2SPeter Wemm 
93c2aa98e2SPeter Wemm 		  case 's':		/* seconds */
94c2aa98e2SPeter Wemm 			break;
95c2aa98e2SPeter Wemm 		}
96c2aa98e2SPeter Wemm 		r += t;
97c2aa98e2SPeter Wemm 	}
98c2aa98e2SPeter Wemm 
9940266059SGregory Neil Shapiro 	return pos ? r : -r;
100c2aa98e2SPeter Wemm }
10140266059SGregory Neil Shapiro /*
102c2aa98e2SPeter Wemm **  PINTVL -- produce printable version of a time interval
103c2aa98e2SPeter Wemm **
104c2aa98e2SPeter Wemm **	Parameters:
105c2aa98e2SPeter Wemm **		intvl -- the interval to be converted
10640266059SGregory Neil Shapiro **		brief -- if true, print this in an extremely compact form
107c2aa98e2SPeter Wemm **			(basically used for logging).
108c2aa98e2SPeter Wemm **
109c2aa98e2SPeter Wemm **	Returns:
110c2aa98e2SPeter Wemm **		A pointer to a string version of intvl suitable for
111c2aa98e2SPeter Wemm **			printing or framing.
112c2aa98e2SPeter Wemm **
113c2aa98e2SPeter Wemm **	Side Effects:
114c2aa98e2SPeter Wemm **		none.
115c2aa98e2SPeter Wemm **
116c2aa98e2SPeter Wemm **	Warning:
117c2aa98e2SPeter Wemm **		The string returned is in a static buffer.
118c2aa98e2SPeter Wemm */
119c2aa98e2SPeter Wemm 
120c2aa98e2SPeter Wemm #define PLURAL(n)	((n) == 1 ? "" : "s")
121c2aa98e2SPeter Wemm 
122c2aa98e2SPeter Wemm char *
123c2aa98e2SPeter Wemm pintvl(intvl, brief)
124c2aa98e2SPeter Wemm 	time_t intvl;
125c2aa98e2SPeter Wemm 	bool brief;
126c2aa98e2SPeter Wemm {
127c2aa98e2SPeter Wemm 	static char buf[256];
128c2aa98e2SPeter Wemm 	register char *p;
129c2aa98e2SPeter Wemm 	int wk, dy, hr, mi, se;
130c2aa98e2SPeter Wemm 
131c2aa98e2SPeter Wemm 	if (intvl == 0 && !brief)
13206f25ae9SGregory Neil Shapiro 		return "zero seconds";
13306f25ae9SGregory Neil Shapiro 	if (intvl == NOW)
13406f25ae9SGregory Neil Shapiro 		return "too long";
135c2aa98e2SPeter Wemm 
136c2aa98e2SPeter Wemm 	/* decode the interval into weeks, days, hours, minutes, seconds */
137c2aa98e2SPeter Wemm 	se = intvl % 60;
138c2aa98e2SPeter Wemm 	intvl /= 60;
139c2aa98e2SPeter Wemm 	mi = intvl % 60;
140c2aa98e2SPeter Wemm 	intvl /= 60;
141c2aa98e2SPeter Wemm 	hr = intvl % 24;
142c2aa98e2SPeter Wemm 	intvl /= 24;
143c2aa98e2SPeter Wemm 	if (brief)
144c2aa98e2SPeter Wemm 	{
145c2aa98e2SPeter Wemm 		dy = intvl;
146c2aa98e2SPeter Wemm 		wk = 0;
147c2aa98e2SPeter Wemm 	}
148c2aa98e2SPeter Wemm 	else
149c2aa98e2SPeter Wemm 	{
150c2aa98e2SPeter Wemm 		dy = intvl % 7;
151c2aa98e2SPeter Wemm 		intvl /= 7;
152c2aa98e2SPeter Wemm 		wk = intvl;
153c2aa98e2SPeter Wemm 	}
154c2aa98e2SPeter Wemm 
155c2aa98e2SPeter Wemm 	/* now turn it into a sexy form */
156c2aa98e2SPeter Wemm 	p = buf;
157c2aa98e2SPeter Wemm 	if (brief)
158c2aa98e2SPeter Wemm 	{
159c2aa98e2SPeter Wemm 		if (dy > 0)
160c2aa98e2SPeter Wemm 		{
16140266059SGregory Neil Shapiro 			(void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy);
162c2aa98e2SPeter Wemm 			p += strlen(p);
163c2aa98e2SPeter Wemm 		}
16440266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
165c2aa98e2SPeter Wemm 				   hr, mi, se);
16606f25ae9SGregory Neil Shapiro 		return buf;
167c2aa98e2SPeter Wemm 	}
168c2aa98e2SPeter Wemm 
169c2aa98e2SPeter Wemm 	/* use the verbose form */
170c2aa98e2SPeter Wemm 	if (wk > 0)
171c2aa98e2SPeter Wemm 	{
17240266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk,
17340266059SGregory Neil Shapiro 				   PLURAL(wk));
174c2aa98e2SPeter Wemm 		p += strlen(p);
175c2aa98e2SPeter Wemm 	}
176c2aa98e2SPeter Wemm 	if (dy > 0)
177c2aa98e2SPeter Wemm 	{
17840266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy,
17940266059SGregory Neil Shapiro 				   PLURAL(dy));
180c2aa98e2SPeter Wemm 		p += strlen(p);
181c2aa98e2SPeter Wemm 	}
182c2aa98e2SPeter Wemm 	if (hr > 0)
183c2aa98e2SPeter Wemm 	{
18440266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr,
18540266059SGregory Neil Shapiro 				   PLURAL(hr));
186c2aa98e2SPeter Wemm 		p += strlen(p);
187c2aa98e2SPeter Wemm 	}
188c2aa98e2SPeter Wemm 	if (mi > 0)
189c2aa98e2SPeter Wemm 	{
19040266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi,
19140266059SGregory Neil Shapiro 				   PLURAL(mi));
192c2aa98e2SPeter Wemm 		p += strlen(p);
193c2aa98e2SPeter Wemm 	}
194c2aa98e2SPeter Wemm 	if (se > 0)
195c2aa98e2SPeter Wemm 	{
19640266059SGregory Neil Shapiro 		(void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se,
19740266059SGregory Neil Shapiro 				   PLURAL(se));
198c2aa98e2SPeter Wemm 		p += strlen(p);
199c2aa98e2SPeter Wemm 	}
200c2aa98e2SPeter Wemm 
201c2aa98e2SPeter Wemm 	return (buf + 2);
202c2aa98e2SPeter Wemm }
203