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