/* $Id: atot.c,v 1.1 2003/03/29 06:19:07 wafer Exp $ */ /* Convert a string to a time value; this is mostly grafted from the * BSD 'date' source, so: */ /* * Copyright (c) 1985, 1987, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #ifndef TM_YEAR_BASE #define TM_YEAR_BASE 1900 #endif #define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0')) void badformat () { fprintf(stderr, "Bad time format\n"); exit(1); } char isdigit (char c) { return c >= '0' && c <= '9'; } void atot (time_t *tval, const char *p) { struct tm *lt = malloc(sizeof(struct tm)); const char *dot, *t; int century; for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t) || *t == ':') continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } time(tval); localtime_r(tval, lt); if (dot != NULL) { /* .ss */ dot++; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; century = 0; /* if p has a ".ss" field then let's pretend it's not there */ switch (strlen(p) - ((dot != NULL) ? 3 : 0)) { case 13: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; century = 1; /* FALLTHROUGH */ case 11: /* yy */ if (century) lt->tm_year += ATOI2(p); else { lt->tm_year = ATOI2(p) + 2000 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 9: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 7: /* dd */ lt->tm_mday = ATOI2(p); if (lt->tm_mday > 31) badformat(); /* FALLTHROUGH */ case 5: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); p++; /* jump over the colon */ /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* Let mktime() decide whether summer time is in effect. */ lt->tm_isdst = -1; /* convert broken-down time to GMT clock time */ if ((*tval = mktime(lt)) == -1) badformat(); free(lt); return; }