Ejemplo n.º 1
0
void
fattime2timespec(unsigned dd, unsigned dt, unsigned dh, int utc, struct timespec *tsp)
{
	unsigned day;

	/* Unpack time fields */
	tsp->tv_sec = (dt & 0x1f) << 1;
	tsp->tv_sec += ((dt & 0x7e0) >> 5) * 60;
	tsp->tv_sec += ((dt & 0xf800) >> 11) * 3600;
	tsp->tv_sec += dh / 100;
	tsp->tv_nsec = (dh % 100) * 10000000;

	/* Day of month */
	day = (dd & 0x1f) - 1;

	/* Full leap-year cycles */
	day += LYC * ((dd >> 11) & 0x1f);

	/* Month offset from leap-year cycle */
	day += daytab[(dd >> 5) & 0x3f];

	/*
	 * 2100 is not a leap year.
	 * XXX: a 32 bit time_t can not get us here.
	 */
	if (day >= ((2100 - 1980) / 4 * LYC + FEB))
		day--;

	/* Align with time_t epoch */
	day += T1980;

	tsp->tv_sec += DAY * day;
	if (!utc)
		tsp->tv_sec += utc_offset();
}
Ejemplo n.º 2
0
static int
efirtc_settime(device_t dev, struct timespec *ts)
{
	struct clocktime ct;
	struct efi_tm tm;

	/*
	 * We request a timespec with no resolution-adjustment so that we can
	 * apply it ourselves based on whether or not the clock zeroes the
	 * sub-second part of the time when setting the time.
	 */
	ts->tv_sec -= utc_offset();
	if (!efirtc_zeroes_subseconds)
		timespecadd(ts, &efirtc_resadj);
	
	clock_ts_to_ct(ts, &ct);
	clock_dbgprint_ct(dev, CLOCK_DBG_WRITE, &ct);

	bzero(&tm, sizeof(tm));
	tm.tm_sec = ct.sec;
	tm.tm_min = ct.min;
	tm.tm_hour = ct.hour;
	tm.tm_mday = ct.day;
	tm.tm_mon = ct.mon;
	tm.tm_year = ct.year;
	tm.tm_nsec = ct.nsec;

	return (efi_set_time(&tm));
}
const char *imap_to_datetime(time_t timestamp)
{
	struct tm *tm;
	int timezone_offset;

	tm = localtime(&timestamp);
	timezone_offset = utc_offset(tm, timestamp);
	return imap_to_datetime_tm(tm, timezone_offset);
}
Ejemplo n.º 4
0
const char *iso8601_date_create(time_t timestamp)
{
	struct tm *tm;
	int timezone_offset;

	tm = localtime(&timestamp);
	timezone_offset = utc_offset(tm, timestamp);
	
	return iso8601_date_create_tm(tm, timezone_offset);
}
Ejemplo n.º 5
0
void
timespec2fattime(struct timespec *tsp, int utc, uint16_t *ddp, uint16_t *dtp, uint8_t *dhp)
{
	time_t t1;
	unsigned t2, l, m;

	t1 = tsp->tv_sec;
	if (!utc)
		t1 -= utc_offset();

	if (dhp != NULL)
		*dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
	if (dtp != NULL) {
		*dtp = (t1 / 2) % 30;
		*dtp |= ((t1 / 60) % 60) << 5;
		*dtp |= ((t1 / 3600) % 24) << 11;
	}
	if (ddp != NULL) {
		t2 = t1 / DAY;
		if (t2 < T1980) {
			/* Impossible date, truncate to 1980-01-01 */
			*ddp = 0x0021;
		} else {
			t2 -= T1980;

			/*
			 * 2100 is not a leap year.
			 * XXX: a 32 bit time_t can not get us here.
			 */
			if (t2 >= ((2100 - 1980) / 4 * LYC + FEB))
				t2++;

			/* Account for full leapyear cycles */
			l = t2 / LYC;
			*ddp = (l * 4) << 9;
			t2 -= l * LYC;

			/* Find approximate table entry */
			m = t2 / 32;

			/* Find correct table entry */
			while (m < 47 && mtab[m + 1].days <= t2)
				m++;

			/* Get year + month from the table */
			*ddp += mtab[m].coded;

			/* And apply the day in the month */
			t2 -= mtab[m].days - 1;
			*ddp |= t2;
		}
	}
}
Ejemplo n.º 6
0
  String* Time::strftime(STATE, String* format) {
    struct tm64 tm = get_tm();

    struct timespec64 ts;
    ts.tv_sec = seconds_;
    ts.tv_nsec = nanoseconds_;

    int off = 0;
    if(Fixnum* offset = try_as<Fixnum>(utc_offset(state))) {
      off = offset->to_int();
    }

    if(format->byte_size() == 0) return String::create(state, NULL, 0);

    char stack_str[STRFTIME_STACK_BUF];

    size_t chars = ::strftime_extended(stack_str, STRFTIME_STACK_BUF,
                       format->c_str(state), &tm, &ts, CBOOL(is_gmt_) ? 1 : 0,
                       off);

    size_t buf_size = format->byte_size();

    String* result = 0;

    if(chars == 0) {
      buf_size *= 2;
      char* malloc_str = (char*)malloc(buf_size);

      if(!malloc_str) {
        Exception::memory_error(state);
        return NULL;
      }

      chars = ::strftime_extended(malloc_str, buf_size,
                  format->c_str(state), &tm, &ts, CBOOL(is_gmt_) ? 1 : 0,
                  off);
      if(chars) {
        result = String::create(state, malloc_str, chars);
        result->encoding(state, format->encoding());
      }

      free(malloc_str);
    } else {
      result = String::create(state, stack_str, chars);
      result->encoding(state, format->encoding());
    }

    return result;
  }
Ejemplo n.º 7
0
/*
 * Write system time back to RTC
 */
void
resettodr(void)
{
	struct timespec ts;
	int error;

	if (disable_rtc_set || clock_dev == NULL)
		return;

	getnanotime(&ts);
	timespecadd(&ts, &clock_adj);
	ts.tv_sec -= utc_offset();
	/* XXX: We should really set all registered RTCs */
	if ((error = CLOCK_SETTIME(clock_dev, &ts)) != 0)
		printf("warning: clock_settime failed (%d), time-of-day clock "
		    "not adjusted to system time\n", error);
}
Ejemplo n.º 8
0
static bool
mail_search_arg_to_imap_date(string_t *dest, const struct mail_search_arg *arg)
{
	time_t timestamp = arg->value.time;
	const char *str;

	if ((arg->value.search_flags &
	     MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) {
		struct tm *tm = localtime(&timestamp);
		int tz_offset = utc_offset(tm, timestamp);
		timestamp -= tz_offset * 60;
	}
	if (!imap_to_date(timestamp, &str))
		return FALSE;
	str_printfa(dest, " \"%s\"", str);
	return TRUE;
}
Ejemplo n.º 9
0
void
tws_aen_synctime_with_host(struct tws_softc *sc)
{

    int error;
    long int sync_time;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);

    sync_time = (TWS_LOCAL_TIME - (3 * 86400)) % 604800;
    TWS_TRACE_DEBUG(sc, "sync_time,ts", sync_time, time_second);
    TWS_TRACE_DEBUG(sc, "utc_offset", utc_offset(), 0);
    error = tws_set_param(sc, TWS_PARAM_TIME_TABLE, TWS_PARAM_TIME_SCHED_TIME,
                           4, &sync_time);
    if ( error )
        TWS_TRACE_DEBUG(sc, "set param failed", sync_time, error);
}
Ejemplo n.º 10
0
/*
 * Initialize the time of day register, based on the time base which is, e.g.
 * from a filesystem.
 */
void
inittodr(time_t base)
{
	struct timespec ts;
	int error;

	if (clock_dev == NULL) {
		printf("warning: no time-of-day clock registered, system time "
		    "will not be set accurately\n");
		goto wrong_time;
	}
	/* XXX: We should poll all registered RTCs in case of failure */
	mtx_lock(&resettodr_lock);
	error = CLOCK_GETTIME(clock_dev, &ts);
	mtx_unlock(&resettodr_lock);
	if (error != 0 && error != EINVAL) {
		printf("warning: clock_gettime failed (%d), the system time "
		    "will not be set accurately\n", error);
		goto wrong_time;
	}
	if (error == EINVAL || ts.tv_sec < 0) {
		printf("Invalid time in real time clock.\n"
		    "Check and reset the date immediately!\n");
		goto wrong_time;
	}

	ts.tv_sec += utc_offset();
	timespecadd(&ts, &clock_adj);
	tc_setclock(&ts);
#ifdef FFCLOCK
	ffclock_reset_clock(&ts);
#endif
	return;

wrong_time:
	if (base > 0) {
		ts.tv_sec = base;
		ts.tv_nsec = 0;
		tc_setclock(&ts);
	}
}
Ejemplo n.º 11
0
const char *message_date_create(time_t timestamp)
{
	struct tm *tm;
	int offset;
	bool negative;

	tm = localtime(&timestamp);
	offset = utc_offset(tm, timestamp);
	if (offset >= 0)
		negative = FALSE;
	else {
		negative = TRUE;
		offset = -offset;
	}

	return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %c%02d%02d",
			       weekday_names[tm->tm_wday],
			       tm->tm_mday,
			       month_names[tm->tm_mon],
			       tm->tm_year+1900,
			       tm->tm_hour, tm->tm_min, tm->tm_sec,
			       negative ? '-' : '+', offset / 60, offset % 60);
}
Ejemplo n.º 12
0
int mbox_from_parse(const unsigned char *msg, size_t size,
		    time_t *time_r, int *tz_offset_r, char **sender_r)
{
	const unsigned char *msg_start, *sender_end, *msg_end;
	struct tm tm;
	int esc, alt_stamp, timezone_secs = 0, seen_timezone = FALSE;
	time_t t;

	*time_r = (time_t)-1;
	*sender_r = NULL;

	/* <sender> <date> <moreinfo> */
	msg_start = msg;
	msg_end = msg + size;

	/* get sender */
	if (msg < msg_end && *msg == '"') {
		/* "x y z"@domain - skip the quoted part */
		esc = FALSE;
		msg++;
		while (msg < msg_end && (*msg != '"' || esc)) {
			if (*msg == '\r' || *msg == '\n')
				return -1;
			esc = *msg == '\\';
			msg++;
		}
		msg++;
	} 

	while (msg < msg_end && *msg != ' ') {
		if (*msg == '\r' || *msg == '\n')
			return -1;
		msg++;
	}
	sender_end = msg;
	while (msg < msg_end && *msg == ' ') msg++;

	/* next 29 chars should be in the date in asctime() format, eg.
	   "Thu Nov  9 22:33:52 2001 +0300"

	   - Some put the timezone before the year
	   - Some use a named timezone before or after year, which we ignore
	   - Some don't include seconds (-3)
	   - Some don't include timezone (-5)
	*/
	if (msg+29-3-5 > msg_end)
		return -1;

	memset(&tm, 0, sizeof(tm));

	/* skip weekday */
	msg += 4;

	/* month */
	if (mbox_parse_month(msg, &tm) < 0) {
		/* Try alternate timestamp: "Thu, 9 Nov 2002 22:33:52" */
		alt_stamp = TRUE;
		msg++;

		if (!i_isdigit(msg[0]))
			return -1;
		tm.tm_mday = msg[0]-'0';
		msg++;

		if (i_isdigit(msg[0])) {
			tm.tm_mday = tm.tm_mday*10 + msg[0]-'0';
			msg++;
		}
		if (msg[0] != ' ')
			return -1;
		msg++;

		if (mbox_parse_month(msg, &tm) < 0)
			return -1;
		msg += 4;

		if (mbox_parse_year(msg, &tm) < 0)
			return -1;
		msg += 5;
	} else {
		alt_stamp = FALSE;
		msg += 4;

		/* day. single digit is usually preceded by extra space */
		if (msg[0] == ' ')
			msg++;
		if (msg[1] == ' ') {
			if (!i_isdigit(msg[0]))
				return -1;
			tm.tm_mday = msg[0]-'0';
			msg += 2;
		} else {
			if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ')
				return -1;
			tm.tm_mday = (msg[0]-'0') * 10 + (msg[1]-'0');
			msg += 3;
		}
	}
	if (tm.tm_mday == 0)
		tm.tm_mday = 1;

	/* hour */
	if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':')
		return -1;
	tm.tm_hour = (msg[0]-'0') * 10 + (msg[1]-'0');
	msg += 3;

	/* minute */
	if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]))
		return -1;
	tm.tm_min = (msg[0]-'0') * 10 + (msg[1]-'0');
	msg += 2;

	/* optional second */
	if (msg[0] == ':') {
		msg++;
		if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]))
			return -1;
		tm.tm_sec = (msg[0]-'0') * 10 + (msg[1]-'0');
		msg += 2;

		if (!alt_stamp) {
			if (msg[0] == ' ')
				msg++;
			else
				return -1;
		}
	} else if (!alt_stamp) {
		if (msg[0] != ' ')
			return -1;
		msg++;
	}

	/* optional named timezone */
	if (alt_stamp)
		;
	else if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) ||
		 !i_isdigit(msg[2]) || !i_isdigit(msg[3])) {
		/* skip to next space */
		while (msg < msg_end && *msg != ' ') {
			if (*msg == '\r' || *msg == '\n')
				return -1;
			msg++;
		}
		if (msg+5 > msg_end)
			return -1;
		msg++;
	} else if ((msg[0] == '-' || msg[0] == '+') &&
		   i_isdigit(msg[1]) && i_isdigit(msg[2]) &&
		   i_isdigit(msg[3]) && i_isdigit(msg[4]) && msg[5] == ' ') {
		/* numeric timezone, use it */
                seen_timezone = TRUE;
		timezone_secs = (msg[1]-'0') * 10*60*60 + (msg[2]-'0') * 60*60 +
			(msg[3]-'0') * 10 + (msg[4]-'0');
		if (msg[0] == '-') timezone_secs = -timezone_secs;
		msg += 6;
	}

	if (!alt_stamp) {
		/* year */
		if (mbox_parse_year(msg, &tm) < 0)
			return -1;
		msg += 4;
	}

	tm.tm_isdst = -1;
	if (!seen_timezone && msg != msg_end &&
	    msg[0] == ' ' && (msg[1] == '-' || msg[1] == '+') &&
	    i_isdigit(msg[2]) && i_isdigit(msg[3]) &&
	    i_isdigit(msg[4]) && i_isdigit(msg[5])) {
		seen_timezone = TRUE;
		timezone_secs = (msg[2]-'0') * 10*60*60 + (msg[3]-'0') * 60*60 +
			(msg[4]-'0') * 10 + (msg[5]-'0');
		if (msg[1] == '-') timezone_secs = -timezone_secs;
	}

	if (seen_timezone) {
		t = utc_mktime(&tm);
		if (t == (time_t)-1)
			return -1;

		t -= timezone_secs;
		*time_r = t;
		*tz_offset_r = timezone_secs/60;
	} else {
		/* assume local timezone */
		*time_r = mktime(&tm);
		*tz_offset_r = utc_offset(localtime(time_r), *time_r);
	}

	*sender_r = i_strdup_until(msg_start, sender_end);
	return 0;
}
Ejemplo n.º 13
0
 /// Number of seconds since midnight in local time zone for a given UTC time.
 static time_t local_seconds_since_midnight(time_t a_utc_time) {
     time_t tm = a_utc_time + utc_offset();
     return tm % 86400;
 }
Ejemplo n.º 14
0
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
static int search_arg_match_cached(struct index_search_context *ctx,
				   struct mail_search_arg *arg)
{
	const char *str;
	struct tm *tm;
	uoff_t virtual_size;
	time_t date;
	int tz_offset;
	bool have_tz_offset;

	switch (arg->type) {
	/* internal dates */
	case SEARCH_BEFORE:
	case SEARCH_ON:
	case SEARCH_SINCE:
		have_tz_offset = FALSE; tz_offset = 0; date = (time_t)-1;
		switch (arg->value.date_type) {
		case MAIL_SEARCH_DATE_TYPE_SENT:
			if (mail_get_date(ctx->mail, &date, &tz_offset) < 0)
				return -1;
			have_tz_offset = TRUE;
			break;
		case MAIL_SEARCH_DATE_TYPE_RECEIVED:
			if (mail_get_received_date(ctx->mail, &date) < 0)
				return -1;
			break;
		case MAIL_SEARCH_DATE_TYPE_SAVED:
			if (mail_get_save_date(ctx->mail, &date) < 0)
				return -1;
			break;
		}

		if ((arg->value.search_flags &
		     MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) {
			if (!have_tz_offset) {
				tm = localtime(&date);
				tz_offset = utc_offset(tm, date);
			}
			date += tz_offset * 60;
		}

		switch (arg->type) {
		case SEARCH_BEFORE:
			return date < arg->value.time;
		case SEARCH_ON:
			return date >= arg->value.time &&
				date < arg->value.time + 3600*24;
		case SEARCH_SINCE:
			return date >= arg->value.time;
		default:
			/* unreachable */
			break;
		}

	/* sizes */
	case SEARCH_SMALLER:
	case SEARCH_LARGER:
		if (mail_get_virtual_size(ctx->mail, &virtual_size) < 0)
			return -1;

		if (arg->type == SEARCH_SMALLER)
			return virtual_size < arg->value.size;
		else
			return virtual_size > arg->value.size;

	case SEARCH_GUID:
		if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &str) < 0)
			return -1;
		return strcmp(str, arg->value.str) == 0;
	default:
		return -1;
	}
}