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