1N/A/*
1N/A * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
1N/A * All rights reserved.
1N/A * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
1N/A * Copyright (c) 1988, 1993
1N/A * The Regents of the University of California. All rights reserved.
1N/A *
1N/A * By using this file, you agree to the terms and conditions set
1N/A * forth in the LICENSE file which can be found at the top level of
1N/A * the sendmail distribution.
1N/A *
1N/A */
1N/A
1N/A#pragma ident "%Z%%M% %I% %E% SMI"
1N/A
1N/A#include <sendmail.h>
1N/A
1N/ASM_RCSID("@(#)$Id: convtime.c,v 8.36 2001/02/13 22:32:08 ca Exp $")
1N/A
1N/A/*
1N/A** CONVTIME -- convert time
1N/A**
1N/A** Takes a time as an ascii string with a trailing character
1N/A** giving units:
1N/A** s -- seconds
1N/A** m -- minutes
1N/A** h -- hours
1N/A** d -- days (default)
1N/A** w -- weeks
1N/A** For example, "3d12h" is three and a half days.
1N/A**
1N/A** Parameters:
1N/A** p -- pointer to ascii time.
1N/A** units -- default units if none specified.
1N/A**
1N/A** Returns:
1N/A** time in seconds.
1N/A**
1N/A** Side Effects:
1N/A** none.
1N/A*/
1N/A
1N/Atime_t
1N/Aconvtime(p, units)
1N/A char *p;
1N/A int units;
1N/A{
1N/A register time_t t, r;
1N/A register char c;
1N/A bool pos = true;
1N/A
1N/A r = 0;
1N/A if (sm_strcasecmp(p, "now") == 0)
1N/A return NOW;
1N/A if (*p == '-')
1N/A {
1N/A pos = false;
1N/A ++p;
1N/A }
1N/A while (*p != '\0')
1N/A {
1N/A t = 0;
1N/A while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
1N/A t = t * 10 + (c - '0');
1N/A if (c == '\0')
1N/A {
1N/A c = units;
1N/A p--;
1N/A }
1N/A else if (strchr("wdhms", c) == NULL)
1N/A {
1N/A usrerr("Invalid time unit `%c'", c);
1N/A c = units;
1N/A }
1N/A switch (c)
1N/A {
1N/A case 'w': /* weeks */
1N/A t *= 7;
1N/A /* FALLTHROUGH */
1N/A
1N/A case 'd': /* days */
1N/A /* FALLTHROUGH */
1N/A default:
1N/A t *= 24;
1N/A /* FALLTHROUGH */
1N/A
1N/A case 'h': /* hours */
1N/A t *= 60;
1N/A /* FALLTHROUGH */
1N/A
1N/A case 'm': /* minutes */
1N/A t *= 60;
1N/A /* FALLTHROUGH */
1N/A
1N/A case 's': /* seconds */
1N/A break;
1N/A }
1N/A r += t;
1N/A }
1N/A
1N/A return pos ? r : -r;
1N/A}
1N/A /*
1N/A** PINTVL -- produce printable version of a time interval
1N/A**
1N/A** Parameters:
1N/A** intvl -- the interval to be converted
1N/A** brief -- if true, print this in an extremely compact form
1N/A** (basically used for logging).
1N/A**
1N/A** Returns:
1N/A** A pointer to a string version of intvl suitable for
1N/A** printing or framing.
1N/A**
1N/A** Side Effects:
1N/A** none.
1N/A**
1N/A** Warning:
1N/A** The string returned is in a static buffer.
1N/A*/
1N/A
1N/A#define PLURAL(n) ((n) == 1 ? "" : "s")
1N/A
1N/Achar *
1N/Apintvl(intvl, brief)
1N/A time_t intvl;
1N/A bool brief;
1N/A{
1N/A static char buf[256];
1N/A register char *p;
1N/A int wk, dy, hr, mi, se;
1N/A
1N/A if (intvl == 0 && !brief)
1N/A return "zero seconds";
1N/A if (intvl == NOW)
1N/A return "too long";
1N/A
1N/A /* decode the interval into weeks, days, hours, minutes, seconds */
1N/A se = intvl % 60;
1N/A intvl /= 60;
1N/A mi = intvl % 60;
1N/A intvl /= 60;
1N/A hr = intvl % 24;
1N/A intvl /= 24;
1N/A if (brief)
1N/A {
1N/A dy = intvl;
1N/A wk = 0;
1N/A }
1N/A else
1N/A {
1N/A dy = intvl % 7;
1N/A intvl /= 7;
1N/A wk = intvl;
1N/A }
1N/A
1N/A /* now turn it into a sexy form */
1N/A p = buf;
1N/A if (brief)
1N/A {
1N/A if (dy > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), "%d+", dy);
1N/A p += strlen(p);
1N/A }
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), "%02d:%02d:%02d",
1N/A hr, mi, se);
1N/A return buf;
1N/A }
1N/A
1N/A /* use the verbose form */
1N/A if (wk > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d week%s", wk,
1N/A PLURAL(wk));
1N/A p += strlen(p);
1N/A }
1N/A if (dy > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d day%s", dy,
1N/A PLURAL(dy));
1N/A p += strlen(p);
1N/A }
1N/A if (hr > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d hour%s", hr,
1N/A PLURAL(hr));
1N/A p += strlen(p);
1N/A }
1N/A if (mi > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d minute%s", mi,
1N/A PLURAL(mi));
1N/A p += strlen(p);
1N/A }
1N/A if (se > 0)
1N/A {
1N/A (void) sm_snprintf(p, SPACELEFT(buf, p), ", %d second%s", se,
1N/A PLURAL(se));
1N/A p += strlen(p);
1N/A }
1N/A
1N/A return (buf + 2);
1N/A}