convtime.c revision 302408
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 16SM_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 41time_t 42convtime(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 122char * 123pintvl(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