1 /*-------------------------------------------------------------------------
2  *
3  * compat.c
4  *		Reimplementations of various backend functions.
5  *
6  * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *		src/bin/pg_waldump/compat.c
10  *
11  * This file contains client-side implementations for various backend
12  * functions that the rm_desc functions in *desc.c files rely on.
13  *
14  *-------------------------------------------------------------------------
15  */
16 
17 /* ugly hack, same as in e.g pg_controldata */
18 #define FRONTEND 1
19 #include "postgres.h"
20 
21 #include <time.h>
22 
23 #include "utils/datetime.h"
24 #include "lib/stringinfo.h"
25 
26 /* copied from timestamp.c */
27 pg_time_t
timestamptz_to_time_t(TimestampTz t)28 timestamptz_to_time_t(TimestampTz t)
29 {
30 	pg_time_t	result;
31 
32 	result = (pg_time_t) (t / USECS_PER_SEC +
33 						  ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
34 	return result;
35 }
36 
37 /*
38  * Stopgap implementation of timestamptz_to_str that doesn't depend on backend
39  * infrastructure.  This will work for timestamps that are within the range
40  * of the platform time_t type.  (pg_time_t is compatible except for possibly
41  * being wider.)
42  *
43  * XXX the return value points to a static buffer, so beware of using more
44  * than one result value concurrently.
45  *
46  * XXX: The backend timestamp infrastructure should instead be split out and
47  * moved into src/common.  That's a large project though.
48  */
49 const char *
timestamptz_to_str(TimestampTz dt)50 timestamptz_to_str(TimestampTz dt)
51 {
52 	static char buf[MAXDATELEN + 1];
53 	char		ts[MAXDATELEN + 1];
54 	char		zone[MAXDATELEN + 1];
55 	time_t		result = (time_t) timestamptz_to_time_t(dt);
56 	struct tm  *ltime = localtime(&result);
57 
58 	strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", ltime);
59 	strftime(zone, sizeof(zone), "%Z", ltime);
60 
61 	snprintf(buf, sizeof(buf), "%s.%06d %s",
62 			 ts, (int) (dt % USECS_PER_SEC), zone);
63 
64 	return buf;
65 }
66 
67 /*
68  * Provide a hacked up compat layer for StringInfos so xlog desc functions can
69  * be linked/called.
70  */
71 void
appendStringInfo(StringInfo str,const char * fmt,...)72 appendStringInfo(StringInfo str, const char *fmt,...)
73 {
74 	va_list		args;
75 
76 	va_start(args, fmt);
77 	vprintf(fmt, args);
78 	va_end(args);
79 }
80 
81 void
appendStringInfoString(StringInfo str,const char * string)82 appendStringInfoString(StringInfo str, const char *string)
83 {
84 	appendStringInfo(str, "%s", string);
85 }
86 
87 void
appendStringInfoChar(StringInfo str,char ch)88 appendStringInfoChar(StringInfo str, char ch)
89 {
90 	appendStringInfo(str, "%c", ch);
91 }
92