138032Speter/* 2261370Sgshapiro * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers. 364562Sgshapiro * All rights reserved. 438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 538032Speter * Copyright (c) 1988, 1993 638032Speter * The Regents of the University of California. All rights reserved. 738032Speter * 838032Speter * By using this file, you agree to the terms and conditions set 938032Speter * forth in the LICENSE file which can be found at the top level of 1038032Speter * the sendmail distribution. 1138032Speter * 1238032Speter */ 1338032Speter 1464562Sgshapiro#include <sendmail.h> 1538032Speter 16266711SgshapiroSM_RCSID("@(#)$Id: convtime.c,v 8.40 2013-11-22 20:51:55 ca Exp $") 1790792Sgshapiro 1838032Speter/* 1938032Speter** CONVTIME -- convert time 2038032Speter** 2138032Speter** Takes a time as an ascii string with a trailing character 2238032Speter** giving units: 2338032Speter** s -- seconds 2438032Speter** m -- minutes 2538032Speter** h -- hours 2638032Speter** d -- days (default) 2738032Speter** w -- weeks 2838032Speter** For example, "3d12h" is three and a half days. 2938032Speter** 3038032Speter** Parameters: 3138032Speter** p -- pointer to ascii time. 3238032Speter** units -- default units if none specified. 3338032Speter** 3438032Speter** Returns: 3538032Speter** time in seconds. 3638032Speter** 3738032Speter** Side Effects: 3838032Speter** none. 3938032Speter*/ 4038032Speter 4138032Spetertime_t 4238032Speterconvtime(p, units) 4338032Speter char *p; 4464562Sgshapiro int units; 4538032Speter{ 4638032Speter register time_t t, r; 4738032Speter register char c; 4890792Sgshapiro bool pos = true; 4938032Speter 5038032Speter r = 0; 5190792Sgshapiro if (sm_strcasecmp(p, "now") == 0) 5264562Sgshapiro return NOW; 5390792Sgshapiro if (*p == '-') 5490792Sgshapiro { 5590792Sgshapiro pos = false; 5690792Sgshapiro ++p; 5790792Sgshapiro } 5838032Speter while (*p != '\0') 5938032Speter { 6038032Speter t = 0; 6138032Speter while ((c = *p++) != '\0' && isascii(c) && isdigit(c)) 6238032Speter t = t * 10 + (c - '0'); 6338032Speter if (c == '\0') 6438032Speter { 6538032Speter c = units; 6638032Speter p--; 6738032Speter } 6838032Speter else if (strchr("wdhms", c) == NULL) 6938032Speter { 7038032Speter usrerr("Invalid time unit `%c'", c); 7138032Speter c = units; 7238032Speter } 7338032Speter switch (c) 7438032Speter { 7538032Speter case 'w': /* weeks */ 7638032Speter t *= 7; 7764562Sgshapiro /* FALLTHROUGH */ 7838032Speter 7938032Speter case 'd': /* days */ 8064562Sgshapiro /* FALLTHROUGH */ 8138032Speter default: 8238032Speter t *= 24; 8364562Sgshapiro /* FALLTHROUGH */ 8438032Speter 8538032Speter case 'h': /* hours */ 8638032Speter t *= 60; 8764562Sgshapiro /* FALLTHROUGH */ 8838032Speter 8938032Speter case 'm': /* minutes */ 9038032Speter t *= 60; 9164562Sgshapiro /* FALLTHROUGH */ 9238032Speter 9338032Speter case 's': /* seconds */ 9438032Speter break; 9538032Speter } 9638032Speter r += t; 9738032Speter } 9838032Speter 9990792Sgshapiro return pos ? r : -r; 10038032Speter} 10190792Sgshapiro/* 10238032Speter** PINTVL -- produce printable version of a time interval 10338032Speter** 10438032Speter** Parameters: 10538032Speter** intvl -- the interval to be converted 10690792Sgshapiro** brief -- if true, print this in an extremely compact form 10738032Speter** (basically used for logging). 10838032Speter** 10938032Speter** Returns: 11038032Speter** A pointer to a string version of intvl suitable for 11138032Speter** printing or framing. 11238032Speter** 11338032Speter** Side Effects: 11438032Speter** none. 11538032Speter** 11638032Speter** Warning: 11738032Speter** The string returned is in a static buffer. 11838032Speter*/ 11938032Speter 12064562Sgshapiro#define PLURAL(n) ((n) == 1 ? "" : "s") 12138032Speter 12238032Speterchar * 12338032Speterpintvl(intvl, brief) 12438032Speter time_t intvl; 12538032Speter bool brief; 12638032Speter{ 12738032Speter static char buf[256]; 12838032Speter register char *p; 12938032Speter int wk, dy, hr, mi, se; 13038032Speter 13138032Speter if (intvl == 0 && !brief) 13264562Sgshapiro return "zero seconds"; 13364562Sgshapiro if (intvl == NOW) 13464562Sgshapiro return "too long"; 13538032Speter 13638032Speter /* decode the interval into weeks, days, hours, minutes, seconds */ 13738032Speter se = intvl % 60; 13838032Speter intvl /= 60; 13938032Speter mi = intvl % 60; 14038032Speter intvl /= 60; 14138032Speter hr = intvl % 24; 14238032Speter intvl /= 24; 14338032Speter if (brief) 14438032Speter { 14538032Speter dy = intvl; 14638032Speter wk = 0; 14738032Speter } 14838032Speter else 14938032Speter { 15038032Speter dy = intvl % 7; 15138032Speter intvl /= 7; 15238032Speter wk = intvl; 15338032Speter } 15438032Speter 15538032Speter /* now turn it into a sexy form */ 15638032Speter p = buf; 15738032Speter if (brief) 15838032Speter { 15938032Speter if (dy > 0) 16038032Speter { 16190792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy); 16238032Speter p += strlen(p); 16338032Speter } 16490792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d", 16590792Sgshapiro hr, mi, se); 16664562Sgshapiro return buf; 16738032Speter } 16838032Speter 16938032Speter /* use the verbose form */ 17038032Speter if (wk > 0) 17138032Speter { 17290792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk, 17390792Sgshapiro PLURAL(wk)); 17438032Speter p += strlen(p); 17538032Speter } 17638032Speter if (dy > 0) 17738032Speter { 17890792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy, 17990792Sgshapiro PLURAL(dy)); 18038032Speter p += strlen(p); 18138032Speter } 18238032Speter if (hr > 0) 18338032Speter { 18490792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr, 18590792Sgshapiro PLURAL(hr)); 18638032Speter p += strlen(p); 18738032Speter } 18838032Speter if (mi > 0) 18938032Speter { 19090792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi, 19190792Sgshapiro PLURAL(mi)); 19238032Speter p += strlen(p); 19338032Speter } 19438032Speter if (se > 0) 19538032Speter { 19690792Sgshapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se, 19790792Sgshapiro PLURAL(se)); 19838032Speter p += strlen(p); 19938032Speter } 20038032Speter 20138032Speter return (buf + 2); 20238032Speter} 203