1c2aa98e2SPeter Wemm /* 2*5dd76dd0SGregory Neil Shapiro * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers. 306f25ae9SGregory Neil Shapiro * All rights reserved. 4c2aa98e2SPeter Wemm * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5c2aa98e2SPeter Wemm * Copyright (c) 1988, 1993 6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved. 7c2aa98e2SPeter Wemm * 8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set 9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of 10c2aa98e2SPeter Wemm * the sendmail distribution. 11c2aa98e2SPeter Wemm * 12c2aa98e2SPeter Wemm */ 13c2aa98e2SPeter Wemm 1406f25ae9SGregory Neil Shapiro #include <sendmail.h> 15c2aa98e2SPeter Wemm 16*5dd76dd0SGregory Neil Shapiro SM_RCSID("@(#)$Id: convtime.c,v 8.40 2013/11/22 20:51:55 ca Exp $") 1740266059SGregory Neil Shapiro 18c2aa98e2SPeter Wemm /* 19c2aa98e2SPeter Wemm ** CONVTIME -- convert time 20c2aa98e2SPeter Wemm ** 21c2aa98e2SPeter Wemm ** Takes a time as an ascii string with a trailing character 22c2aa98e2SPeter Wemm ** giving units: 23c2aa98e2SPeter Wemm ** s -- seconds 24c2aa98e2SPeter Wemm ** m -- minutes 25c2aa98e2SPeter Wemm ** h -- hours 26c2aa98e2SPeter Wemm ** d -- days (default) 27c2aa98e2SPeter Wemm ** w -- weeks 28c2aa98e2SPeter Wemm ** For example, "3d12h" is three and a half days. 29c2aa98e2SPeter Wemm ** 30c2aa98e2SPeter Wemm ** Parameters: 31c2aa98e2SPeter Wemm ** p -- pointer to ascii time. 32c2aa98e2SPeter Wemm ** units -- default units if none specified. 33c2aa98e2SPeter Wemm ** 34c2aa98e2SPeter Wemm ** Returns: 35c2aa98e2SPeter Wemm ** time in seconds. 36c2aa98e2SPeter Wemm ** 37c2aa98e2SPeter Wemm ** Side Effects: 38c2aa98e2SPeter Wemm ** none. 39c2aa98e2SPeter Wemm */ 40c2aa98e2SPeter Wemm 41c2aa98e2SPeter Wemm time_t 42c2aa98e2SPeter Wemm convtime(p, units) 43c2aa98e2SPeter Wemm char *p; 4406f25ae9SGregory Neil Shapiro int units; 45c2aa98e2SPeter Wemm { 46c2aa98e2SPeter Wemm register time_t t, r; 47c2aa98e2SPeter Wemm register char c; 4840266059SGregory Neil Shapiro bool pos = true; 49c2aa98e2SPeter Wemm 50c2aa98e2SPeter Wemm r = 0; 5140266059SGregory Neil Shapiro if (sm_strcasecmp(p, "now") == 0) 5206f25ae9SGregory Neil Shapiro return NOW; 5340266059SGregory Neil Shapiro if (*p == '-') 5440266059SGregory Neil Shapiro { 5540266059SGregory Neil Shapiro pos = false; 5640266059SGregory Neil Shapiro ++p; 5740266059SGregory Neil Shapiro } 58c2aa98e2SPeter Wemm while (*p != '\0') 59c2aa98e2SPeter Wemm { 60c2aa98e2SPeter Wemm t = 0; 61c2aa98e2SPeter Wemm while ((c = *p++) != '\0' && isascii(c) && isdigit(c)) 62c2aa98e2SPeter Wemm t = t * 10 + (c - '0'); 63c2aa98e2SPeter Wemm if (c == '\0') 64c2aa98e2SPeter Wemm { 65c2aa98e2SPeter Wemm c = units; 66c2aa98e2SPeter Wemm p--; 67c2aa98e2SPeter Wemm } 68c2aa98e2SPeter Wemm else if (strchr("wdhms", c) == NULL) 69c2aa98e2SPeter Wemm { 70c2aa98e2SPeter Wemm usrerr("Invalid time unit `%c'", c); 71c2aa98e2SPeter Wemm c = units; 72c2aa98e2SPeter Wemm } 73c2aa98e2SPeter Wemm switch (c) 74c2aa98e2SPeter Wemm { 75c2aa98e2SPeter Wemm case 'w': /* weeks */ 76c2aa98e2SPeter Wemm t *= 7; 7706f25ae9SGregory Neil Shapiro /* FALLTHROUGH */ 78c2aa98e2SPeter Wemm 79c2aa98e2SPeter Wemm case 'd': /* days */ 8006f25ae9SGregory Neil Shapiro /* FALLTHROUGH */ 81c2aa98e2SPeter Wemm default: 82c2aa98e2SPeter Wemm t *= 24; 8306f25ae9SGregory Neil Shapiro /* FALLTHROUGH */ 84c2aa98e2SPeter Wemm 85c2aa98e2SPeter Wemm case 'h': /* hours */ 86c2aa98e2SPeter Wemm t *= 60; 8706f25ae9SGregory Neil Shapiro /* FALLTHROUGH */ 88c2aa98e2SPeter Wemm 89c2aa98e2SPeter Wemm case 'm': /* minutes */ 90c2aa98e2SPeter Wemm t *= 60; 9106f25ae9SGregory Neil Shapiro /* FALLTHROUGH */ 92c2aa98e2SPeter Wemm 93c2aa98e2SPeter Wemm case 's': /* seconds */ 94c2aa98e2SPeter Wemm break; 95c2aa98e2SPeter Wemm } 96c2aa98e2SPeter Wemm r += t; 97c2aa98e2SPeter Wemm } 98c2aa98e2SPeter Wemm 9940266059SGregory Neil Shapiro return pos ? r : -r; 100c2aa98e2SPeter Wemm } 10140266059SGregory Neil Shapiro /* 102c2aa98e2SPeter Wemm ** PINTVL -- produce printable version of a time interval 103c2aa98e2SPeter Wemm ** 104c2aa98e2SPeter Wemm ** Parameters: 105c2aa98e2SPeter Wemm ** intvl -- the interval to be converted 10640266059SGregory Neil Shapiro ** brief -- if true, print this in an extremely compact form 107c2aa98e2SPeter Wemm ** (basically used for logging). 108c2aa98e2SPeter Wemm ** 109c2aa98e2SPeter Wemm ** Returns: 110c2aa98e2SPeter Wemm ** A pointer to a string version of intvl suitable for 111c2aa98e2SPeter Wemm ** printing or framing. 112c2aa98e2SPeter Wemm ** 113c2aa98e2SPeter Wemm ** Side Effects: 114c2aa98e2SPeter Wemm ** none. 115c2aa98e2SPeter Wemm ** 116c2aa98e2SPeter Wemm ** Warning: 117c2aa98e2SPeter Wemm ** The string returned is in a static buffer. 118c2aa98e2SPeter Wemm */ 119c2aa98e2SPeter Wemm 120c2aa98e2SPeter Wemm #define PLURAL(n) ((n) == 1 ? "" : "s") 121c2aa98e2SPeter Wemm 122c2aa98e2SPeter Wemm char * 123c2aa98e2SPeter Wemm pintvl(intvl, brief) 124c2aa98e2SPeter Wemm time_t intvl; 125c2aa98e2SPeter Wemm bool brief; 126c2aa98e2SPeter Wemm { 127c2aa98e2SPeter Wemm static char buf[256]; 128c2aa98e2SPeter Wemm register char *p; 129c2aa98e2SPeter Wemm int wk, dy, hr, mi, se; 130c2aa98e2SPeter Wemm 131c2aa98e2SPeter Wemm if (intvl == 0 && !brief) 13206f25ae9SGregory Neil Shapiro return "zero seconds"; 13306f25ae9SGregory Neil Shapiro if (intvl == NOW) 13406f25ae9SGregory Neil Shapiro return "too long"; 135c2aa98e2SPeter Wemm 136c2aa98e2SPeter Wemm /* decode the interval into weeks, days, hours, minutes, seconds */ 137c2aa98e2SPeter Wemm se = intvl % 60; 138c2aa98e2SPeter Wemm intvl /= 60; 139c2aa98e2SPeter Wemm mi = intvl % 60; 140c2aa98e2SPeter Wemm intvl /= 60; 141c2aa98e2SPeter Wemm hr = intvl % 24; 142c2aa98e2SPeter Wemm intvl /= 24; 143c2aa98e2SPeter Wemm if (brief) 144c2aa98e2SPeter Wemm { 145c2aa98e2SPeter Wemm dy = intvl; 146c2aa98e2SPeter Wemm wk = 0; 147c2aa98e2SPeter Wemm } 148c2aa98e2SPeter Wemm else 149c2aa98e2SPeter Wemm { 150c2aa98e2SPeter Wemm dy = intvl % 7; 151c2aa98e2SPeter Wemm intvl /= 7; 152c2aa98e2SPeter Wemm wk = intvl; 153c2aa98e2SPeter Wemm } 154c2aa98e2SPeter Wemm 155c2aa98e2SPeter Wemm /* now turn it into a sexy form */ 156c2aa98e2SPeter Wemm p = buf; 157c2aa98e2SPeter Wemm if (brief) 158c2aa98e2SPeter Wemm { 159c2aa98e2SPeter Wemm if (dy > 0) 160c2aa98e2SPeter Wemm { 16140266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy); 162c2aa98e2SPeter Wemm p += strlen(p); 163c2aa98e2SPeter Wemm } 16440266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d", 165c2aa98e2SPeter Wemm hr, mi, se); 16606f25ae9SGregory Neil Shapiro return buf; 167c2aa98e2SPeter Wemm } 168c2aa98e2SPeter Wemm 169c2aa98e2SPeter Wemm /* use the verbose form */ 170c2aa98e2SPeter Wemm if (wk > 0) 171c2aa98e2SPeter Wemm { 17240266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk, 17340266059SGregory Neil Shapiro PLURAL(wk)); 174c2aa98e2SPeter Wemm p += strlen(p); 175c2aa98e2SPeter Wemm } 176c2aa98e2SPeter Wemm if (dy > 0) 177c2aa98e2SPeter Wemm { 17840266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy, 17940266059SGregory Neil Shapiro PLURAL(dy)); 180c2aa98e2SPeter Wemm p += strlen(p); 181c2aa98e2SPeter Wemm } 182c2aa98e2SPeter Wemm if (hr > 0) 183c2aa98e2SPeter Wemm { 18440266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr, 18540266059SGregory Neil Shapiro PLURAL(hr)); 186c2aa98e2SPeter Wemm p += strlen(p); 187c2aa98e2SPeter Wemm } 188c2aa98e2SPeter Wemm if (mi > 0) 189c2aa98e2SPeter Wemm { 19040266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi, 19140266059SGregory Neil Shapiro PLURAL(mi)); 192c2aa98e2SPeter Wemm p += strlen(p); 193c2aa98e2SPeter Wemm } 194c2aa98e2SPeter Wemm if (se > 0) 195c2aa98e2SPeter Wemm { 19640266059SGregory Neil Shapiro (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se, 19740266059SGregory Neil Shapiro PLURAL(se)); 198c2aa98e2SPeter Wemm p += strlen(p); 199c2aa98e2SPeter Wemm } 200c2aa98e2SPeter Wemm 201c2aa98e2SPeter Wemm return (buf + 2); 202c2aa98e2SPeter Wemm } 203