cmogstored.git  about / heads / tags
alternative mogstored implementation for MogileFS
blob 1c711324e13d3168ff19f914f56aad20675b54f5 1459 bytes (raw)
$ git show HEAD:http_date.c	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
/*
 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 */
#include "cmogstored.h"

/* avoiding strftime() since it's locale-aware */

#define DATELEN (MOG_HTTPDATE_CAPA - 1)
static const char week[] = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat";
static const char months[] = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0"
                             "Jul\0Aug\0Sep\0Oct\0Nov\0Dec";

__attribute__((constructor)) static void http_date_init(void)
{
	time_t now = time(NULL);
	struct tm tm;

	/*
	 * call gmtime_r once in the main loop to load, TZ info.
	 * Initial run uses a lot of stack on *BSDs
	 */
	gmtime_r(&now, &tm);
}

char *mog_http_date(char *dst, size_t len, const time_t *timep)
{
	int rc;
	struct tm tm;

	assert(len >= MOG_HTTPDATE_CAPA && "date length incorrect");
	gmtime_r(timep, &tm);

	/* snprintf eats stack :( */
	rc = snprintf(dst, len, "%s, %02d %s %4d %02d:%02d:%02d GMT",
			 week + (tm.tm_wday * 4),
			 tm.tm_mday,
			 months + (tm.tm_mon * 4),
			 tm.tm_year + 1900,
			 tm.tm_hour,
			 tm.tm_min,
			 tm.tm_sec);
	assert(rc == DATELEN && "bad sprintf return value");

	return dst + rc;
}

struct mog_now *mog_now(void)
{
	static __thread struct mog_now now;
	time_t tnow = time(NULL); /* not a syscall on modern 64-bit systems */

	if (now.ntime == tnow)
		return &now;

	now.ntime = tnow;
	mog_http_date(now.httpdate, sizeof(now.httpdate), &tnow);

	return &now;
}

git clone https://yhbt.net/cmogstored.git