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