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