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 /* 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 } 194