xref: /freebsd/contrib/sendmail/src/convtime.c (revision 6e8394b8baa7d5d9153ab90de6824bcd19b3b4e1)
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
14 static char sccsid[] = "@(#)convtime.c	8.14 (Berkeley) 5/19/1998";
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 
42 time_t
43 convtime(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 
110 char *
111 pintvl(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