示例#1
0
static time_t
parsetime(char *p)
{
	struct tm *lt;
	int bigyear;
	int yearset = 0;
	time_t tval;
	char *t;
	
	for (t = p; *t; ++t) {
		if (isdigit((unsigned char) *t))
			continue;
		badformat();
	}

	tval = time(NULL);
	lt = localtime(&tval);
	lt->tm_sec = 0;
	lt->tm_min = 0;

	switch (strlen(p)) {
	case 10:				/* yyyy */
		bigyear = ATOI2(p);
		lt->tm_year = bigyear * 100 - 1900;
		yearset = 1;
		/* FALLTHROUGH */
	case 8:					/* yy */
		if (yearset) {
			lt->tm_year += ATOI2(p);
		} else {
			lt->tm_year = ATOI2(p);
			if (lt->tm_year < 69)		/* hack for 2000 */
				lt->tm_year += 100;
		}
		/* FALLTHROUGH */
	case 6:					/* mm */
		lt->tm_mon = ATOI2(p);
		if ((lt->tm_mon > 12) || !lt->tm_mon)
			badformat();
		--lt->tm_mon;			/* time struct is 0 - 11 */
		/* FALLTHROUGH */
	case 4:					/* dd */
		lt->tm_mday = ATOI2(p);
		if ((lt->tm_mday > 31) || !lt->tm_mday)
			badformat();
		/* FALLTHROUGH */
	case 2:					/* HH */
		lt->tm_hour = ATOI2(p);
		if (lt->tm_hour > 23)
			badformat();
		break;
	default:
		badformat();
	}
	/* The calling code needs a valid tm_ydays and this is the easiest
	 * way to get one */
	if ((tval = mktime(lt)) == -1)
		errx(1, "specified date is outside allowed range");
	return (tval);
}
示例#2
0
文件: date.c 项目: Ptr-mat/bitrig
void
setthetime(char *p)
{
	struct tm *lt;
	struct timeval tv;
	char *dot, *t;
	int yearset = 0;

	for (t = p, dot = NULL; *t; ++t) {
		if (isdigit((unsigned char)*t))
			continue;
		if (*t == '.' && dot == NULL) {
			dot = t;
			continue;
		}
		badformat();
	}

	lt = localtime(&tval);

	lt->tm_isdst = -1;			/* correct for DST */

	if (dot != NULL) {			/* .SS */
		*dot++ = '\0';
		if (strlen(dot) != 2)
			badformat();
		lt->tm_sec = ATOI2(dot);
		if (lt->tm_sec > 61)
			badformat();
	} else
		lt->tm_sec = 0;

	switch (strlen(p)) {
	case 12:				/* cc */
		lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
		yearset = 1;
		/* FALLTHROUGH */
	case 10:				/* yy */
		if (!yearset) {
			/* mask out current year, leaving only century */
			lt->tm_year = ((lt->tm_year / 100) * 100);
		}
		lt->tm_year += ATOI2(p);
		/* FALLTHROUGH */
	case 8:					/* mm */
		lt->tm_mon = ATOI2(p);
		if ((lt->tm_mon > 12) || !lt->tm_mon)
			badformat();
		--lt->tm_mon;			/* time struct is 0 - 11 */
		/* FALLTHROUGH */
	case 6:					/* dd */
		lt->tm_mday = ATOI2(p);
		if ((lt->tm_mday > 31) || !lt->tm_mday)
			badformat();
		/* FALLTHROUGH */
	case 4:					/* HH */
		lt->tm_hour = ATOI2(p);
		if (lt->tm_hour > 23)
			badformat();
		/* FALLTHROUGH */
	case 2:					/* MM */
		lt->tm_min = ATOI2(p);
		if (lt->tm_min > 59)
			badformat();
		break;
	default:
		badformat();
	}

	/* convert broken-down time to UTC clock time */
	if ((tval = mktime(lt)) < 0)
		errx(1, "specified date is outside allowed range");

	if (jflag)
		return;

	/* set the time */
	if (slidetime) {
		struct timeval tv_current;

		if (gettimeofday(&tv_current, NULL) == -1)
			err(1, "Could not get local time of day");

		tv.tv_sec = tval - tv_current.tv_sec;
		tv.tv_usec = 0;
		if (adjtime(&tv, NULL) == -1)
			errx(1, "adjtime");
	} else {
#ifndef SMALL
		logwtmp("|", "date", "");
#endif
		tv.tv_sec = tval;
		tv.tv_usec = 0;
		if (settimeofday(&tv, NULL))
			err(1, "settimeofday");
#ifndef SMALL
		logwtmp("{", "date", "");
#endif
	}

	if ((p = getlogin()) == NULL)
		p = "???";
	syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
}
示例#3
0
static void
setthetime(const char *fmt, const char *p, int jflag, int nflag)
{
	struct utmpx utx;
	struct tm *lt;
	struct timeval tv;
	const char *dot, *t;
	int century;

	lt = localtime(&tval);
	lt->tm_isdst = -1;		/* divine correct DST */

	if (fmt != NULL) {
		t = strptime(p, fmt, lt);
		if (t == NULL) {
			fprintf(stderr, "Failed conversion of ``%s''"
				" using format ``%s''\n", p, fmt);
			badformat();
		} else if (*t != '\0')
			fprintf(stderr, "Warning: Ignoring %ld extraneous"
				" characters in date string (%s)\n",
				(long) strlen(t), t);
	} else {
		for (t = p, dot = NULL; *t; ++t) {
			if (isdigit(*t))
				continue;
			if (*t == '.' && dot == NULL) {
				dot = t;
				continue;
			}
			badformat();
		}

		if (dot != NULL) {			/* .ss */
			dot++; /* *dot++ = '\0'; */
			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 12:				/* cc */
			lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
			century = 1;
			/* FALLTHROUGH */
		case 10:				/* yy */
			if (century)
				lt->tm_year += ATOI2(p);
			else {
				lt->tm_year = ATOI2(p);
				if (lt->tm_year < 69)	/* hack for 2000 ;-} */
					lt->tm_year += 2000 - TM_YEAR_BASE;
				else
					lt->tm_year += 1900 - TM_YEAR_BASE;
			}
			/* FALLTHROUGH */
		case 8:					/* mm */
			lt->tm_mon = ATOI2(p);
			if (lt->tm_mon > 12)
				badformat();
			--lt->tm_mon;		/* time struct is 0 - 11 */
			/* FALLTHROUGH */
		case 6:					/* dd */
			lt->tm_mday = ATOI2(p);
			if (lt->tm_mday > 31)
				badformat();
			/* FALLTHROUGH */
		case 4:					/* HH */
			lt->tm_hour = ATOI2(p);
			if (lt->tm_hour > 23)
				badformat();
			/* FALLTHROUGH */
		case 2:					/* MM */
			lt->tm_min = ATOI2(p);
			if (lt->tm_min > 59)
				badformat();
			break;
		default:
			badformat();
		}
	}

	/* convert broken-down time to GMT clock time */
	if ((tval = mktime(lt)) == -1)
		errx(1, "nonexistent time");

	if (!jflag) {
		/* set the time */
		if (nflag || netsettime(tval)) {
			utx.ut_type = OLD_TIME;
			gettimeofday(&utx.ut_tv, NULL);
			pututxline(&utx);
			tv.tv_sec = tval;
			tv.tv_usec = 0;
			if (settimeofday(&tv, (struct timezone *)NULL))
				err(1, "settimeofday (timeval)");
			utx.ut_type = NEW_TIME;
			gettimeofday(&utx.ut_tv, NULL);
			pututxline(&utx);
		}

		if ((p = getlogin()) == NULL)
			p = "???";
		syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
	}
}
示例#4
0
文件: date.c 项目: wbx-github/openadk
void
setthetime(char *p)
{
	struct tm *lt;
	struct timeval tv;
	char *dot, *t;
	const char *pc;
	int bigyear;
	int yearset = 0;

	for (t = p, dot = NULL; *t; ++t) {
		if (isdigit(*t))
			continue;
		if (*t == '.' && dot == NULL) {
			dot = t;
			continue;
		}
		badformat();
	}

	lt = localtime(&tval);

	lt->tm_isdst = -1;			/* correct for DST */

	if (dot != NULL) {			/* .SS */
		*dot++ = '\0';
		if (strlen(dot) != 2)
			badformat();
		lt->tm_sec = ATOI2(dot);
		if (lt->tm_sec > 61)
			badformat();
	} else
		lt->tm_sec = 0;

	switch (strlen(p)) {
	case 12:				/* cc */
		bigyear = ATOI2(p);
		lt->tm_year = bigyear * 100 - TM_YEAR_BASE;
		yearset = 1;
		/* FALLTHROUGH */
	case 10:				/* yy */
		if (yearset) {
			lt->tm_year += ATOI2(p);
		} else {
			lt->tm_year = ATOI2(p);
			if (lt->tm_year < 69)		/* hack for 2000 ;-} */
				lt->tm_year += (2000 - TM_YEAR_BASE);
			else
				lt->tm_year += (1900 - TM_YEAR_BASE);
		}
		/* FALLTHROUGH */
	case 8:					/* mm */
		lt->tm_mon = ATOI2(p);
		if ((lt->tm_mon > 12) || !lt->tm_mon)
			badformat();
		--lt->tm_mon;			/* time struct is 0 - 11 */
		/* FALLTHROUGH */
	case 6:					/* dd */
		lt->tm_mday = ATOI2(p);
		if ((lt->tm_mday > 31) || !lt->tm_mday)
			badformat();
		/* FALLTHROUGH */
	case 4:					/* HH */
		lt->tm_hour = ATOI2(p);
		if (lt->tm_hour > 23)
			badformat();
		/* FALLTHROUGH */
	case 2:					/* MM */
		lt->tm_min = ATOI2(p);
		if (lt->tm_min > 59)
			badformat();
		break;
	default:
		badformat();
	}

	/* convert broken-down time to UTC clock time */
	if ((tval = mktime(lt)) < 0)
		errx(1, "specified date is outside allowed range");

	/* set the time */
	if (slidetime) {
		struct timeval tv_current;

		if (gettimeofday(&tv_current, NULL) == -1)
			err(1, "Could not get local time of day");

		tv.tv_sec = tval - tv_current.tv_sec;
		tv.tv_usec = 0;
		if (adjtime(&tv, NULL) == -1)
			errx(1, "adjtime");
	} else {
		tv.tv_sec = tval;
		tv.tv_usec = 0;
		if (settimeofday(&tv, NULL))
			err(1, "settimeofday");
	}

	if ((pc = getlogin()) == NULL)
		pc = "???";
	syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", pc);
}
示例#5
0
main(int argc, char **argv)
{
    char c;
    extern char *optarg;
    malloc_options = "A";
    a = 0;
    while ((c = getopt(argc, argv, "f:i:M:l:m:r:N")) != -1) {
        switch (c) {
        case 'N':
            mem_pools_on = 0;
            break;
        case 'r':
            run_stats = atoi(optarg);
            break;
        case 'f':
            fn = xstrdup(optarg);
            fp = fopen(fn, "r");
            break;
        case 'i':
            initsiz = atoi(optarg);
            break;
        case 'l':
            mem_max_size = atoi(optarg) * 1024 * 1024;
            break;
        case 'M':
            maxsiz = atoi(optarg);
            break;
        case 'm':
            minchunk = atoi(optarg);
            break;
        default:
            fprintf(stderr,
                    "Usage: %s -f file -M maxsiz -i initsiz -m minchunk", argv[0]);
            exit(1);
        }

    }
    if (!fp) {
        fprintf(stderr,
                "%s pummels %s\n%s . o O ( You't supply a valid tracefile.)\n",
                argv[0], getenv("USER"), argv[0]);
        exit(1);
    }
#ifdef WITH_LIB
    sizeToPoolInit();
#endif
    mem_table = hash_create(ptrcmp, 229, hash4);    /* small hash table */
    init_stats();
    while (fgets(mbuf, 256, fp) != NULL) {
        if (run_stats > 0 && (++a) % run_stats == 0)
            print_stats();
        p = NULL;
        switch (mbuf[0]) {
        case 'm':       /* malloc */
            p = strtok(&mbuf[2], ":");
            if (!p)
                badformat();
            size = atoi(p);
            p = strtok(NULL, "\n");
            if (!p)
                badformat();
            mi = malloc(sizeof(memitem));
            strcpy(mi->orig_ptr, p);
            mi->size = size;
            size2id(size, mi);
            mi->my_ptr = xmemAlloc(mi);     /* (void *)xmalloc(size); */
            assert(mi->my_ptr);
            my_hash_insert(mem_table, mi->orig_ptr, mi);
            mstat.mallocs++;
            break;
        case 'c':       /* calloc */
            p = strtok(&mbuf[2], ":");
            if (!p)
                badformat();
            amt = atoi(p);
            p = strtok(NULL, ":");
            if (!p)
                badformat();
            size = atoi(p);
            p = strtok(NULL, "\n");
            if (!p)
                badformat();
            mi = malloc(sizeof(memitem));
            strcpy(mi->orig_ptr, p);
            size2id(size, mi);
            mi->size = amt * size;
            mi->my_ptr = xmemAlloc(mi);     /*(void *)xmalloc(amt*size); */
            assert(mi->my_ptr);
            my_hash_insert(mem_table, mi->orig_ptr, mi);
            mstat.callocs++;
            break;
        case 'r':
            p = strtok(&mbuf[2], ":");
            if (!p)
                badformat();
            strcpy(abuf, p);
            p = strtok(NULL, ":");
            if (!p)
                badformat();
            mem_entry = hash_lookup(mem_table, p);
            if (mem_entry == NULL) {
                fprintf(stderr, "invalid realloc (%s)!\n", p);
                break;
            }
            mi = (memitem *) (mem_entry->item);
            assert(mi->pool);
            assert(mi->my_ptr);
            xmemFree(mi);   /* xfree(mi->my_ptr); */
            size2id(atoi(p), mi);   /* we don't need it here I guess? */
            strcpy(mi->orig_ptr, abuf);
            p = strtok(NULL, "\n");
            if (!p)
                badformat();
            mi->my_ptr = xmemAlloc(mi);     /* (char *)xmalloc(atoi(p)); */
            assert(mi->my_ptr);
            mstat.reallocs++;
            break;
        case 'f':
            p = strtok(&mbuf[2], "\n");
            mem_entry = hash_lookup(mem_table, p);
            if (mem_entry == NULL) {
                if (p[0] != '0')
                    fprintf(stderr, "invalid free (%s) at line %d!\n", p, a);
                break;
            }
            mi = (memitem *) (mem_entry->item);
            assert(mi->pool);
            assert(mi->my_ptr);
            xmemFree(mi);   /* xfree(mi->my_ptr); */
            hash_unlink(mem_table, mem_entry, 1);
            free(mi);
            mstat.frees++;
            break;
        default:
            fprintf(stderr, "%s pummels %s.bad.format\n", argv[0], fn);
            exit(1);
        }

    }
    fclose(fp);
    print_stats();
}
示例#6
0
int
convert_TI_records(
    FILE *ifp,
    char *inm,
    FILE *ofp,
    char *onm)
{
    char buff[512];
    char *p;
    int c;
    bool endrecord = FALSE;
    bool eol;
    buffer_rec tb;

    while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
    {
        if (p[strlen(p)-1] == '\n')                 /* get rid of newline */
            p[strlen(p)-1] = '\0';

        if (p[strlen(p)-1] == '\r')                 /* get rid of any CR */
            p[strlen(p)-1] = '\0';

        tb.dl_count = 0;

        p = &buff[0];
        eol = FALSE;
        while ( ! eol && ! endrecord)
        {
            switch (*p++)
            {
                case '9':
                    if (tb.dl_count)
                        write_record(&tb, ofp);
                    tb.dl_destaddr = get2bytes(&p);
                    break;

                case 'B':
                    c = getbyte(&p);
                    filesum += c;
                    tb.dl_buf[tb.dl_count++] = c;
                    c = getbyte(&p);
                    filesum += c;
                    tb.dl_buf[tb.dl_count++] = c;
                    break;

                case 'F':
                    eol = TRUE;
                    break;

                case ':':
                    endrecord = TRUE;
                    break;

                default:
                    badformat(p, inm, BADFMT);
            }
        }
        if (tb.dl_count)
            write_record(&tb, ofp);
    }
    return 0;
}
示例#7
0
int
convert_S_records(
    FILE *ifp,
    char *inm,
    FILE *ofp,
    char *onm)
{
    char buff[512];
    char *p;
    u8 cksum;
    int incksum;
    int c;
    int len;                        /* data length of current line */
    int rectype;                    /* record type */
    u32 addr;
    bool endrecord = FALSE;
    buffer_rec tb;

    while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
    {
        p = &buff[0];

        if (p[strlen(p)-1] == '\n')                 /* get rid of newline */
            p[strlen(p)-1] = '\0';

        if (p[strlen(p)-1] == '\r')                 /* get rid of any CR */
            p[strlen(p)-1] = '\0';

        tb.dl_count = 0;

        if (*p != 'S')
            badformat(p, inm, BADFMT);
        p++;

        if ((rectype = getnibble(&p)) == -1)        /* record type */
            badformat(buff, inm, BADTYPE);

        if ((len = getbyte(&p)) == -1)              /* record len */
            badformat(buff, inm, BADLEN);
        cksum = len;

        switch (rectype)
        {
            case 0x00:                  /* comment field, ignored */
                goto write_it;

            case 0x01:                          /* data record, 16 bit addr */
                if ((addr = get2bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);
                len -= 3;
                goto doit;

            case 0x02:                          /* ... 24 bit addr */
                if ((addr = get3bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);
                len -= 4;
                goto doit;

            case 0x03:                          /* ... 32 bit addr */
                if ((addr = get4bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);
                len -= 5;
    doit:
                cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);

                tb.dl_destaddr = addr;
                while (len--)
                {
                    if ((c = getbyte(&p)) == -1)
                        badformat(buff, inm, BADDATA);
                    cksum += c;
                    filesum += c;
                    tb.dl_buf[tb.dl_count++] = c;
                }
                break;

            case 0x07:                  /* 32 bit end record */
                if ((addr = get4bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);
                goto end_rec;

            case 0x08:                  /* 24 bit end record */
                if ((addr = get3bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);
                goto end_rec;

            case 0x09:                  /* 16 bit end record */
                if ((addr = get2bytes(&p)) == -1L)
                    badformat(buff, inm, BADADDR);

end_rec:
                cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
                tb.dl_jumpaddr = addr;
                break;

            default:
                error(0, "unknown Motorola-S record type: 0x%02x", rectype);
                badformat(buff, inm, BADTYPE);
                break;
        }

        /*
         * Verify checksums are correct in file.
         */

        cksum = (~cksum) & 0xff;
        if ((incksum = getbyte(&p)) == -1)
            badformat(buff, inm, BADCSUM);
        if (((u8) incksum) != cksum)
            badformat(buff, inm, MISCSUM);

write_it:
        if (tb.dl_count)
            write_record(&tb, ofp);
    }
    return 0;
}
示例#8
0
int
convert_Intel_records(
    FILE *ifp,
    char *inm,
    FILE *ofp,
    char *onm)
{
    char buff[512];
    char *p;
    u8 cksum;
    int incksum;
    int c;
    int rectype;                    /* record type */
    int len;                        /* data length of current line */
    u32 addr;
    u32 base_address = 0;
    bool endrecord = FALSE;
    buffer_rec tb;

    while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
    {
        p = &buff[0];

        if (p[strlen(p)-1] == '\n')                 /* get rid of newline */
            p[strlen(p)-1] = '\0';

        if (p[strlen(p)-1] == '\r')                 /* get rid of any CR */
            p[strlen(p)-1] = '\0';

        tb.dl_count = 0;

        if (*p != ':')
            badformat(p, inm, BADFMT);
        p++;

        if ((len = getbyte(&p)) == -1)      /* record len */
            badformat(buff, inm, BADLEN);

        if ((addr = get2bytes(&p)) == -1L)          /* record addr */
            badformat(buff, inm, BADADDR);

        rectype = getbyte(&p);

        cksum = len + B0(addr) + B1(addr) + rectype;

        switch (rectype)
        {
            case 0x00:                  /* normal data record */
                tb.dl_destaddr = base_address + addr;
                while (len--)
                {
                    if ((c = getbyte(&p)) == -1)
                        badformat(buff, inm, BADDATA);
                    cksum += c;
                    filesum += c;
                    tb.dl_buf[tb.dl_count++] = c;
                }
                break;

            case 0x01:                  /* execution start address */
                base_address = addr;
                endrecord = TRUE;
                break;

            case 0x02:                  /* new base */
                if ((base_address = get2bytes(&p)) == -1L)
                    badformat(buff, inm, BADBASE);
                cksum += B0(base_address) + B1(base_address);
                base_address <<= 4;
                break;

            case 0x03:                  /* seg/off execution start address */
            {
                u32 seg, off;

                seg = get2bytes(&p);
                off = get2bytes(&p);
                if ((seg == -1L) || (off == -1L))
                    badformat(buff, inm, BADADDR);

                cksum += B0(seg) + B1(seg) + B0(off) + B1(off);

                tb.dl_jumpaddr = (seg << 4) + off;
                break;
            }

            default:
                error(0, "unknown Intel-hex record type: 0x%02x", rectype);
                badformat(buff, inm, BADTYPE);
        }

        /*
         * Verify checksums are correct in file.
         */

        cksum = (-cksum) & 0xff;
        if ((incksum = getbyte(&p)) == -1)
            badformat(buff, inm, BADCSUM);
        if (((u8) incksum) != cksum)
            badformat(buff, inm, MISCSUM);

        if (tb.dl_count)
            write_record(&tb, ofp);
    }
    return 0;
}
示例#9
0
int
unhex(FILE *ifp,
      char *inm,
      FILE *ofp,
      char *onm)
{
    int c;

    filesum = 0;

    /*
     * Make sure holes will be filled with 0xFF's if requested.  We
     *  do this the easy way by just filling the file with FF's before
     *  getting started.  To do it more optimally would be quite a bit
     *  more difficult since the user can skip around as much as he/she
     *  likes in the input hex file addressing.
     *
     *  We'll clean this up later (after this program has run) with
     *  'stripffs'
     */

    if (FFfill)
    {
        (void) fseek(ofp, 0, 0);
        for (c = FFfill; c > 0; c--)
            (void) fputc(0xFF, ofp);
    }

    /*
     * Read the first char from file and determine record types
     */

    if ((c = getc(ifp)) != EOF)
    {
        ungetc(c, ifp);
        switch(c)
        {
            case 'S':
                convert_S_records(ifp, inm, ofp, onm);
                break;

            case ':':
                convert_Intel_records(ifp, inm, ofp, onm);
                break;

            case '9':
            case 'B':
                convert_TI_records(ifp, inm, ofp, onm);
                break;

            default:
            {
                char tmp[2];
                tmp[0] = c; tmp[1] = 0;
                badformat(tmp, inm, BADFMT);
            }
        }
    }

    if (verbose)
        fprintf(stderr, "'%s' checksum is 0x%04x\n", inm, filesum);

    return 0;
}
示例#10
0
static void
setthetime(const char *p)
{
	struct timeval tv;
	time_t new_time;
	struct tm *lt;
	const char *dot, *t;
	size_t len;
	int yearset;

	for (t = p, dot = NULL; *t; ++t) {
		if (isdigit((unsigned char)*t))
			continue;
		if (*t == '.' && dot == NULL) {
			dot = t;
			continue;
		}
		badformat();
	}

	lt = localtime(&tval);

	lt->tm_isdst = -1;			/* Divine correct DST */

	if (dot != NULL) {			/* .ss */
		len = strlen(dot);
		if (len != 3)
			badformat();
		++dot;
		lt->tm_sec = ATOI2(dot);
		if (lt->tm_sec > 61)
			badvalue("seconds");
	} else {
		len = 0;
		lt->tm_sec = 0;
	}

	yearset = 0;
	switch (strlen(p) - len) {
	case 12:				/* cc */
		lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
		if (lt->tm_year < 0)
			badtime();
		yearset = 1;
		/* FALLTHROUGH */
	case 10:				/* yy */
		if (yearset) {
			lt->tm_year += ATOI2(p);
		} else {
			yearset = ATOI2(p);
			if (yearset < 69)
				lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
			else
				lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
		}
		/* FALLTHROUGH */
	case 8:					/* mm */
		lt->tm_mon = ATOI2(p);
		if (lt->tm_mon > 12 || lt->tm_mon == 0)
			badvalue("month");
		--lt->tm_mon;			/* time struct is 0 - 11 */
		/* FALLTHROUGH */
	case 6:					/* dd */
		lt->tm_mday = ATOI2(p);
		switch (lt->tm_mon) {
		case 0:
		case 2:
		case 4:
		case 6:
		case 7:
		case 9:
		case 11:
			if (lt->tm_mday > 31 || lt->tm_mday == 0)
				badvalue("day of month");
			break;
		case 3:
		case 5:
		case 8:
		case 10:
			if (lt->tm_mday > 30 || lt->tm_mday == 0)
				badvalue("day of month");
			break;
		case 1:
			if (lt->tm_mday > 29 || lt->tm_mday == 0 ||
			    (lt->tm_mday == 29 &&
			     !isleap(lt->tm_year + TM_YEAR_BASE)))
				badvalue("day of month");
			break;
		default:
			badvalue("month");
			break;
		}
		/* FALLTHROUGH */
	case 4:					/* hh */
		lt->tm_hour = ATOI2(p);
		if (lt->tm_hour > 23)
			badvalue("hour");
		/* FALLTHROUGH */
	case 2:					/* mm */
		lt->tm_min = ATOI2(p);
		if (lt->tm_min > 59)
			badvalue("minute");
		break;
	case 0:					/* was just .sss */
		if (len != 0)
			break;
		/* FALLTHROUGH */
	default:
		badformat();
	}

	/* convert broken-down time to UTC clock time */
	if ((new_time = mktime(lt)) == -1)
		badtime();

	/* if jflag is set, don't actually change the time, just return */
	if (jflag) {
		tval = new_time;
		return;
	}

	/* set the time */
	if (nflag || netsettime(new_time)) {
		logwtmp("|", "date", "");
		if (aflag) {
			tv.tv_sec = new_time - tval;
			tv.tv_usec = 0;
			if (adjtime(&tv, NULL))
				err(EXIT_FAILURE, "adjtime");
		} else {
			tval = new_time;
			tv.tv_sec = tval;
			tv.tv_usec = 0;
			if (settimeofday(&tv, NULL))
				err(EXIT_FAILURE, "settimeofday");
		}
		logwtmp("{", "date", "");
	}

	if ((p = getlogin()) == NULL)
		p = "???";
	syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
}