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