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