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