Пример #1
0
static void
getoffset(char *timearg)
{
    struct tm *lt;
    char *p;
    time_t now;
    int this_year;

    (void)time(&now);

    if (!strcasecmp(timearg, "now")) {		/* now */
        offset = 0;
        shuttime = now;
        return;
    }

    if (*timearg == '+') {				/* +minutes */
        if (!isdigit(*++timearg))
            badtime();
        if ((offset = atoi(timearg) * 60) < 0)
            badtime();
        shuttime = now + offset;
        return;
    }

    /* handle hh:mm by getting rid of the colon */
    for (p = timearg; *p; ++p)
        if (!isascii(*p) || !isdigit(*p)) {
            if (*p == ':' && strlen(p) == 3) {
                p[0] = p[1];
                p[1] = p[2];
                p[2] = '\0';
            }
            else
                badtime();
        }

    unsetenv("TZ");					/* OUR timezone */
    lt = localtime(&now);				/* current time val */

    switch(strlen(timearg)) {
    case 10:
        this_year = lt->tm_year;
        lt->tm_year = ATOI2(timearg);
        /*
         * check if the specified year is in the next century.
         * allow for one year of user error as many people will
         * enter n - 1 at the start of year n.
         */
        if (lt->tm_year < (this_year % 100) - 1)
            lt->tm_year += 100;
        /* adjust for the year 2000 and beyond */
        lt->tm_year += (this_year - (this_year % 100));
    /* FALLTHROUGH */
    case 8:
        lt->tm_mon = ATOI2(timearg);
        if (--lt->tm_mon < 0 || lt->tm_mon > 11)
            badtime();
    /* FALLTHROUGH */
    case 6:
        lt->tm_mday = ATOI2(timearg);
        if (lt->tm_mday < 1 || lt->tm_mday > 31)
            badtime();
    /* FALLTHROUGH */
    case 4:
        lt->tm_hour = ATOI2(timearg);
        if (lt->tm_hour < 0 || lt->tm_hour > 23)
            badtime();
        lt->tm_min = ATOI2(timearg);
        if (lt->tm_min < 0 || lt->tm_min > 59)
            badtime();
        lt->tm_sec = 0;
        if ((shuttime = mktime(lt)) == -1)
            badtime();
        if ((offset = shuttime - now) < 0)
            errx(1, "that time is already past.");
        break;
    default:
        badtime();
    }
}
Пример #2
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);
}