This commit is contained in:
blue-lemon0104
2026-04-07 13:35:22 +08:00
commit 0120fa9ce3
1530 changed files with 424864 additions and 0 deletions

21
db_include/common/archive.h Executable file
View File

@@ -0,0 +1,21 @@
/*-------------------------------------------------------------------------
*
* archive.h
* Common WAL archive routines
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/archive.h
*
*-------------------------------------------------------------------------
*/
#ifndef ARCHIVE_H
#define ARCHIVE_H
extern char *BuildRestoreCommand(const char *restoreCommand,
const char *xlogpath, /* %p */
const char *xlogfname, /* %f */
const char *lastRestartPointFname); /* %r */
#endif /* ARCHIVE_H */

19
db_include/common/base64.h Executable file
View File

@@ -0,0 +1,19 @@
/*
* base64.h
* Encoding and decoding routines for base64 without whitespace
* support.
*
* Portions Copyright (c) 2001-2021, PostgreSQL Global Development Group
*
* src/include/common/base64.h
*/
#ifndef BASE64_H
#define BASE64_H
/* base 64 */
extern int pg_b64_encode(const char *src, int len, char *dst, int dstlen);
extern int pg_b64_decode(const char *src, int len, char *dst, int dstlen);
extern int pg_b64_enc_len(int srclen);
extern int pg_b64_dec_len(int srclen);
#endif /* BASE64_H */

View File

@@ -0,0 +1,72 @@
/*-------------------------------------------------------------------------
*
* checksum_helper.h
* Compute a checksum of any of various types using common routines
*
* Portions Copyright (c) 2016-2021, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/include/common/checksum_helper.h
*
*-------------------------------------------------------------------------
*/
#ifndef CHECKSUM_HELPER_H
#define CHECKSUM_HELPER_H
#include "common/cryptohash.h"
#include "common/sha2.h"
#include "port/pg_crc32c.h"
/*
* Supported checksum types. It's not necessarily the case that code using
* these functions needs a cryptographically strong checksum; it may only
* need to detect accidental modification. That's why we include CRC-32C: it's
* much faster than any of the other algorithms. On the other hand, we omit
* MD5 here because any new that does need a cryptographically strong checksum
* should use something better.
*/
typedef enum pg_checksum_type
{
CHECKSUM_TYPE_NONE,
CHECKSUM_TYPE_CRC32C,
CHECKSUM_TYPE_SHA224,
CHECKSUM_TYPE_SHA256,
CHECKSUM_TYPE_SHA384,
CHECKSUM_TYPE_SHA512
} pg_checksum_type;
/*
* This is just a union of all applicable context types.
*/
typedef union pg_checksum_raw_context
{
pg_crc32c c_crc32c;
pg_cryptohash_ctx *c_sha2;
} pg_checksum_raw_context;
/*
* This structure provides a convenient way to pass the checksum type and the
* checksum context around together.
*/
typedef struct pg_checksum_context
{
pg_checksum_type type;
pg_checksum_raw_context raw_context;
} pg_checksum_context;
/*
* This is the longest possible output for any checksum algorithm supported
* by this file.
*/
#define PG_CHECKSUM_MAX_LENGTH PG_SHA512_DIGEST_LENGTH
extern bool pg_checksum_parse_type(char *name, pg_checksum_type *);
extern char *pg_checksum_type_name(pg_checksum_type);
extern int pg_checksum_init(pg_checksum_context *, pg_checksum_type);
extern int pg_checksum_update(pg_checksum_context *, const uint8 *input,
size_t len);
extern int pg_checksum_final(pg_checksum_context *, uint8 *output);
#endif

21
db_include/common/config_info.h Executable file
View File

@@ -0,0 +1,21 @@
/*
* config_info.h
* Common code for pg_config output
*
* Copyright (c) 2016-2021, PostgreSQL Global Development Group
*
* src/include/common/config_info.h
*/
#ifndef COMMON_CONFIG_INFO_H
#define COMMON_CONFIG_INFO_H
typedef struct ConfigData
{
char *name;
char *setting;
} ConfigData;
extern ConfigData *get_configdata(const char *my_exec_path,
size_t *configdata_len);
#endif /* COMMON_CONFIG_INFO_H */

28
db_include/common/connect.h Executable file
View File

@@ -0,0 +1,28 @@
/*-------------------------------------------------------------------------
*
* Interfaces in support of FE/BE connections.
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/connect.h
*
*-------------------------------------------------------------------------
*/
#ifndef CONNECT_H
#define CONNECT_H
/*
* This SQL statement installs an always-secure search path, so malicious
* users can't take control. CREATE of an unqualified name will fail, because
* this selects no creation schema. This does not demote pg_temp, so it is
* suitable where we control the entire FE/BE connection but not suitable in
* SECURITY DEFINER functions. This is portable to PostgreSQL 7.3, which
* introduced schemas. When connected to an older version from code that
* might work with the old server, skip this.
*/
#define ALWAYS_SECURE_SEARCH_PATH_SQL \
"SELECT pg_catalog.set_config('search_path', '', false);"
#endif /* CONNECT_H */

View File

@@ -0,0 +1,19 @@
/*
* controldata_utils.h
* Common code for pg_controldata output
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/controldata_utils.h
*/
#ifndef COMMON_CONTROLDATA_UTILS_H
#define COMMON_CONTROLDATA_UTILS_H
#include "catalog/pg_control.h"
extern ControlFileData *get_controlfile(const char *DataDir, bool *crc_ok_p);
extern void update_controlfile(const char *DataDir,
ControlFileData *ControlFile, bool do_sync);
#endif /* COMMON_CONTROLDATA_UTILS_H */

38
db_include/common/cryptohash.h Executable file
View File

@@ -0,0 +1,38 @@
/*-------------------------------------------------------------------------
*
* cryptohash.h
* Generic headers for cryptographic hash functions.
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/common/cryptohash.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_CRYPTOHASH_H
#define PG_CRYPTOHASH_H
/* Context Structures for each hash function */
typedef enum
{
PG_MD5 = 0,
PG_SHA1,
PG_SHA224,
PG_SHA256,
PG_SHA384,
PG_SHA512
} pg_cryptohash_type;
/* opaque context, private to each cryptohash implementation */
typedef struct pg_cryptohash_ctx pg_cryptohash_ctx;
extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type);
extern int pg_cryptohash_init(pg_cryptohash_ctx *ctx);
extern int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len);
extern int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len);
extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx);
#endif /* PG_CRYPTOHASH_H */

45
db_include/common/fe_memutils.h Executable file
View File

@@ -0,0 +1,45 @@
/*
* fe_memutils.h
* memory management support for frontend code
*
* Copyright (c) 2003-2021, PostgreSQL Global Development Group
*
* src/include/common/fe_memutils.h
*/
#ifndef FE_MEMUTILS_H
#define FE_MEMUTILS_H
/*
* Flags for pg_malloc_extended and palloc_extended, deliberately named
* the same as the backend flags.
*/
#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) not
* actually used for frontends */
#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */
#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */
/*
* "Safe" memory allocation functions --- these exit(1) on failure
* (except pg_malloc_extended with MCXT_ALLOC_NO_OOM)
*/
extern char *pg_strdup(const char *in);
extern void *pg_malloc(size_t size);
extern void *pg_malloc0(size_t size);
extern void *pg_malloc_extended(size_t size, int flags);
extern void *pg_realloc(void *pointer, size_t size);
extern void pg_free(void *pointer);
/* Equivalent functions, deliberately named the same as backend functions */
extern char *pstrdup(const char *in);
extern char *pnstrdup(const char *in, Size size);
extern void *palloc(Size size);
extern void *palloc0(Size size);
extern void *palloc_extended(Size size, int flags);
extern void *repalloc(void *pointer, Size size);
extern void pfree(void *pointer);
/* sprintf into a palloc'd buffer --- these are in psprintf.c */
extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);
#endif /* FE_MEMUTILS_H */

56
db_include/common/file_perm.h Executable file
View File

@@ -0,0 +1,56 @@
/*-------------------------------------------------------------------------
*
* File and directory permission definitions
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/file_perm.h
*
*-------------------------------------------------------------------------
*/
#ifndef FILE_PERM_H
#define FILE_PERM_H
#include <sys/stat.h>
/*
* Mode mask for data directory permissions that only allows the owner to
* read/write directories and files.
*
* This is the default.
*/
#define PG_MODE_MASK_OWNER (S_IRWXG | S_IRWXO)
/*
* Mode mask for data directory permissions that also allows group read/execute.
*/
#define PG_MODE_MASK_GROUP (S_IWGRP | S_IRWXO)
/* Default mode for creating directories */
#define PG_DIR_MODE_OWNER S_IRWXU
/* Mode for creating directories that allows group read/execute */
#define PG_DIR_MODE_GROUP (S_IRWXU | S_IRGRP | S_IXGRP)
/* Default mode for creating files */
#define PG_FILE_MODE_OWNER (S_IRUSR | S_IWUSR)
/* Mode for creating files that allows group read */
#define PG_FILE_MODE_GROUP (S_IRUSR | S_IWUSR | S_IRGRP)
/* Modes for creating directories and files in the data directory */
extern int pg_dir_create_mode;
extern int pg_file_create_mode;
/* Mode mask to pass to umask() */
extern int pg_mode_mask;
/* Set permissions and mask based on the provided mode */
extern void SetDataDirectoryCreatePerm(int dataDirMode);
/* Set permissions and mask based on the mode of the data directory */
extern bool GetDataDirectoryCreatePerm(const char *dataDir);
#endif /* FILE_PERM_H */

40
db_include/common/file_utils.h Executable file
View File

@@ -0,0 +1,40 @@
/*-------------------------------------------------------------------------
*
* Assorted utility functions to work on files.
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/file_utils.h
*
*-------------------------------------------------------------------------
*/
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#include <dirent.h>
typedef enum PGFileType
{
PGFILETYPE_ERROR,
PGFILETYPE_UNKNOWN,
PGFILETYPE_REG,
PGFILETYPE_DIR,
PGFILETYPE_LNK
} PGFileType;
#ifdef FRONTEND
extern int fsync_fname(const char *fname, bool isdir);
extern void fsync_pgdata(const char *pg_data, int serverVersion);
extern void fsync_dir_recurse(const char *dir);
extern int durable_rename(const char *oldfile, const char *newfile);
extern int fsync_parent_path(const char *fname);
#endif
extern PGFileType get_dirent_type(const char *path,
const struct dirent *de,
bool look_through_symlinks,
int elevel);
#endif /* FILE_UTILS_H */

104
db_include/common/hashfn.h Executable file
View File

@@ -0,0 +1,104 @@
/*
* Utilities for working with hash values.
*
* Portions Copyright (c) 2017-2021, PostgreSQL Global Development Group
*/
#ifndef HASHFN_H
#define HASHFN_H
/*
* Rotate the high 32 bits and the low 32 bits separately. The standard
* hash function sometimes rotates the low 32 bits by one bit when
* combining elements. We want extended hash functions to be compatible with
* that algorithm when the seed is 0, so we can't just do a normal rotation.
* This works, though.
*/
#define ROTATE_HIGH_AND_LOW_32BITS(v) \
((((v) << 1) & UINT64CONST(0xfffffffefffffffe)) | \
(((v) >> 31) & UINT64CONST(0x100000001)))
extern uint32 hash_bytes(const unsigned char *k, int keylen);
extern uint64 hash_bytes_extended(const unsigned char *k,
int keylen, uint64 seed);
extern uint32 hash_bytes_uint32(uint32 k);
extern uint64 hash_bytes_uint32_extended(uint32 k, uint64 seed);
#ifndef FRONTEND
static inline Datum
hash_any(const unsigned char *k, int keylen)
{
return UInt32GetDatum(hash_bytes(k, keylen));
}
static inline Datum
hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
{
return UInt64GetDatum(hash_bytes_extended(k, keylen, seed));
}
static inline Datum
hash_uint32(uint32 k)
{
return UInt32GetDatum(hash_bytes_uint32(k));
}
static inline Datum
hash_uint32_extended(uint32 k, uint64 seed)
{
return UInt64GetDatum(hash_bytes_uint32_extended(k, seed));
}
#endif
extern uint32 string_hash(const void *key, Size keysize);
extern uint32 tag_hash(const void *key, Size keysize);
extern uint32 uint32_hash(const void *key, Size keysize);
#define oid_hash uint32_hash /* Remove me eventually */
/*
* Combine two 32-bit hash values, resulting in another hash value, with
* decent bit mixing.
*
* Similar to boost's hash_combine().
*/
static inline uint32
hash_combine(uint32 a, uint32 b)
{
a ^= b + 0x9e3779b9 + (a << 6) + (a >> 2);
return a;
}
/*
* Combine two 64-bit hash values, resulting in another hash value, using the
* same kind of technique as hash_combine(). Testing shows that this also
* produces good bit mixing.
*/
static inline uint64
hash_combine64(uint64 a, uint64 b)
{
/* 0x49a0f4dd15e5a8e3 is 64bit random data */
a ^= b + UINT64CONST(0x49a0f4dd15e5a8e3) + (a << 54) + (a >> 7);
return a;
}
/*
* Simple inline murmur hash implementation hashing a 32 bit integer, for
* performance.
*/
static inline uint32
murmurhash32(uint32 data)
{
uint32 h = data;
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
#endif /* HASHFN_H */

29
db_include/common/hmac.h Executable file
View File

@@ -0,0 +1,29 @@
/*-------------------------------------------------------------------------
*
* hmac.h
* Generic headers for HMAC
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/common/hmac.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_HMAC_H
#define PG_HMAC_H
#include "common/cryptohash.h"
/* opaque context, private to each HMAC implementation */
typedef struct pg_hmac_ctx pg_hmac_ctx;
extern pg_hmac_ctx *pg_hmac_create(pg_cryptohash_type type);
extern int pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len);
extern int pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len);
extern int pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len);
extern void pg_hmac_free(pg_hmac_ctx *ctx);
#endif /* PG_HMAC_H */

437
db_include/common/int.h Executable file
View File

@@ -0,0 +1,437 @@
/*-------------------------------------------------------------------------
*
* int.h
* Routines to perform integer math, while checking for overflows.
*
* The routines in this file are intended to be well defined C, without
* relying on compiler flags like -fwrapv.
*
* To reduce the overhead of these routines try to use compiler intrinsics
* where available. That's not that important for the 16, 32 bit cases, but
* the 64 bit cases can be considerably faster with intrinsics. In case no
* intrinsics are available 128 bit math is used where available.
*
* Copyright (c) 2017-2021, PostgreSQL Global Development Group
*
* src/include/common/int.h
*
*-------------------------------------------------------------------------
*/
#ifndef COMMON_INT_H
#define COMMON_INT_H
/*---------
* The following guidelines apply to all the routines:
* - If a + b overflows, return true, otherwise store the result of a + b
* into *result. The content of *result is implementation defined in case of
* overflow.
* - If a - b overflows, return true, otherwise store the result of a - b
* into *result. The content of *result is implementation defined in case of
* overflow.
* - If a * b overflows, return true, otherwise store the result of a * b
* into *result. The content of *result is implementation defined in case of
* overflow.
*---------
*/
/*------------------------------------------------------------------------
* Overflow routines for signed integers
*------------------------------------------------------------------------
*/
/*
* INT16
*/
static inline bool
pg_add_s16_overflow(int16 a, int16 b, int16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#else
int32 res = (int32) a + (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int16) res;
return false;
#endif
}
static inline bool
pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#else
int32 res = (int32) a - (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int16) res;
return false;
#endif
}
static inline bool
pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#else
int32 res = (int32) a * (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int16) res;
return false;
#endif
}
/*
* INT32
*/
static inline bool
pg_add_s32_overflow(int32 a, int32 b, int32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#else
int64 res = (int64) a + (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int32) res;
return false;
#endif
}
static inline bool
pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#else
int64 res = (int64) a - (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int32) res;
return false;
#endif
}
static inline bool
pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#else
int64 res = (int64) a * (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int32) res;
return false;
#endif
}
/*
* INT64
*/
static inline bool
pg_add_s64_overflow(int64 a, int64 b, int64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#elif defined(HAVE_INT128)
int128 res = (int128) a + (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int64) res;
return false;
#else
if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
(a < 0 && b < 0 && a < PG_INT64_MIN - b))
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a + b;
return false;
#endif
}
static inline bool
pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#elif defined(HAVE_INT128)
int128 res = (int128) a - (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int64) res;
return false;
#else
if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
(a > 0 && b < 0 && a > PG_INT64_MAX + b))
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a - b;
return false;
#endif
}
static inline bool
pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#elif defined(HAVE_INT128)
int128 res = (int128) a * (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (int64) res;
return false;
#else
/*
* Overflow can only happen if at least one value is outside the range
* sqrt(min)..sqrt(max) so check that first as the division can be quite a
* bit more expensive than the multiplication.
*
* Multiplying by 0 or 1 can't overflow of course and checking for 0
* separately avoids any risk of dividing by 0. Be careful about dividing
* INT_MIN by -1 also, note reversing the a and b to ensure we're always
* dividing it by a positive value.
*
*/
if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||
b > PG_INT32_MAX || b < PG_INT32_MIN) &&
a != 0 && a != 1 && b != 0 && b != 1 &&
((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||
(a > 0 && b < 0 && b < PG_INT64_MIN / a) ||
(a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
(a < 0 && b < 0 && a < PG_INT64_MAX / b)))
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a * b;
return false;
#endif
}
/*------------------------------------------------------------------------
* Overflow routines for unsigned integers
*------------------------------------------------------------------------
*/
/*
* UINT16
*/
static inline bool
pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#else
uint16 res = a + b;
if (res < a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = res;
return false;
#endif
}
static inline bool
pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#else
if (b > a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a - b;
return false;
#endif
}
static inline bool
pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#else
uint32 res = (uint32) a * (uint32) b;
if (res > PG_UINT16_MAX)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (uint16) res;
return false;
#endif
}
/*
* INT32
*/
static inline bool
pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#else
uint32 res = a + b;
if (res < a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = res;
return false;
#endif
}
static inline bool
pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#else
if (b > a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a - b;
return false;
#endif
}
static inline bool
pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#else
uint64 res = (uint64) a * (uint64) b;
if (res > PG_UINT32_MAX)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (uint32) res;
return false;
#endif
}
/*
* UINT64
*/
static inline bool
pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_add_overflow(a, b, result);
#else
uint64 res = a + b;
if (res < a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = res;
return false;
#endif
}
static inline bool
pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_sub_overflow(a, b, result);
#else
if (b > a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a - b;
return false;
#endif
}
static inline bool
pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
return __builtin_mul_overflow(a, b, result);
#elif defined(HAVE_INT128)
uint128 res = (uint128) a * (uint128) b;
if (res > PG_UINT64_MAX)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = (uint64) res;
return false;
#else
uint64 res = a * b;
if (a != 0 && b != res / a)
{
*result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = res;
return false;
#endif
}
#endif /* COMMON_INT_H */

276
db_include/common/int128.h Executable file
View File

@@ -0,0 +1,276 @@
/*-------------------------------------------------------------------------
*
* int128.h
* Roll-our-own 128-bit integer arithmetic.
*
* We make use of the native int128 type if there is one, otherwise
* implement things the hard way based on two int64 halves.
*
* See src/tools/testint128.c for a simple test harness for this file.
*
* Copyright (c) 2017-2021, PostgreSQL Global Development Group
*
* src/include/common/int128.h
*
*-------------------------------------------------------------------------
*/
#ifndef INT128_H
#define INT128_H
/*
* For testing purposes, use of native int128 can be switched on/off by
* predefining USE_NATIVE_INT128.
*/
#ifndef USE_NATIVE_INT128
#ifdef HAVE_INT128
#define USE_NATIVE_INT128 1
#else
#define USE_NATIVE_INT128 0
#endif
#endif
#if USE_NATIVE_INT128
typedef int128 INT128;
/*
* Add an unsigned int64 value into an INT128 variable.
*/
static inline void
int128_add_uint64(INT128 *i128, uint64 v)
{
*i128 += v;
}
/*
* Add a signed int64 value into an INT128 variable.
*/
static inline void
int128_add_int64(INT128 *i128, int64 v)
{
*i128 += v;
}
/*
* Add the 128-bit product of two int64 values into an INT128 variable.
*
* XXX with a stupid compiler, this could actually be less efficient than
* the other implementation; maybe we should do it by hand always?
*/
static inline void
int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
{
*i128 += (int128) x * (int128) y;
}
/*
* Compare two INT128 values, return -1, 0, or +1.
*/
static inline int
int128_compare(INT128 x, INT128 y)
{
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}
/*
* Widen int64 to INT128.
*/
static inline INT128
int64_to_int128(int64 v)
{
return (INT128) v;
}
/*
* Convert INT128 to int64 (losing any high-order bits).
* This also works fine for casting down to uint64.
*/
static inline int64
int128_to_int64(INT128 val)
{
return (int64) val;
}
#else /* !USE_NATIVE_INT128 */
/*
* We lay out the INT128 structure with the same content and byte ordering
* that a native int128 type would (probably) have. This makes no difference
* for ordinary use of INT128, but allows union'ing INT128 with int128 for
* testing purposes.
*/
typedef struct
{
#ifdef WORDS_BIGENDIAN
int64 hi; /* most significant 64 bits, including sign */
uint64 lo; /* least significant 64 bits, without sign */
#else
uint64 lo; /* least significant 64 bits, without sign */
int64 hi; /* most significant 64 bits, including sign */
#endif
} INT128;
/*
* Add an unsigned int64 value into an INT128 variable.
*/
static inline void
int128_add_uint64(INT128 *i128, uint64 v)
{
/*
* First add the value to the .lo part, then check to see if a carry needs
* to be propagated into the .hi part. A carry is needed if both inputs
* have high bits set, or if just one input has high bit set while the new
* .lo part doesn't. Remember that .lo part is unsigned; we cast to
* signed here just as a cheap way to check the high bit.
*/
uint64 oldlo = i128->lo;
i128->lo += v;
if (((int64) v < 0 && (int64) oldlo < 0) ||
(((int64) v < 0 || (int64) oldlo < 0) && (int64) i128->lo >= 0))
i128->hi++;
}
/*
* Add a signed int64 value into an INT128 variable.
*/
static inline void
int128_add_int64(INT128 *i128, int64 v)
{
/*
* This is much like the above except that the carry logic differs for
* negative v. Ordinarily we'd need to subtract 1 from the .hi part
* (corresponding to adding the sign-extended bits of v to it); but if
* there is a carry out of the .lo part, that cancels and we do nothing.
*/
uint64 oldlo = i128->lo;
i128->lo += v;
if (v >= 0)
{
if ((int64) oldlo < 0 && (int64) i128->lo >= 0)
i128->hi++;
}
else
{
if (!((int64) oldlo < 0 || (int64) i128->lo >= 0))
i128->hi--;
}
}
/*
* INT64_AU32 extracts the most significant 32 bits of int64 as int64, while
* INT64_AL32 extracts the least significant 32 bits as uint64.
*/
#define INT64_AU32(i64) ((i64) >> 32)
#define INT64_AL32(i64) ((i64) & UINT64CONST(0xFFFFFFFF))
/*
* Add the 128-bit product of two int64 values into an INT128 variable.
*/
static inline void
int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
{
/* INT64_AU32 must use arithmetic right shift */
StaticAssertStmt(((int64) -1 >> 1) == (int64) -1,
"arithmetic right shift is needed");
/*----------
* Form the 128-bit product x * y using 64-bit arithmetic.
* Considering each 64-bit input as having 32-bit high and low parts,
* we can compute
*
* x * y = ((x.hi << 32) + x.lo) * (((y.hi << 32) + y.lo)
* = (x.hi * y.hi) << 64 +
* (x.hi * y.lo) << 32 +
* (x.lo * y.hi) << 32 +
* x.lo * y.lo
*
* Each individual product is of 32-bit terms so it won't overflow when
* computed in 64-bit arithmetic. Then we just have to shift it to the
* correct position while adding into the 128-bit result. We must also
* keep in mind that the "lo" parts must be treated as unsigned.
*----------
*/
/* No need to work hard if product must be zero */
if (x != 0 && y != 0)
{
int64 x_u32 = INT64_AU32(x);
uint64 x_l32 = INT64_AL32(x);
int64 y_u32 = INT64_AU32(y);
uint64 y_l32 = INT64_AL32(y);
int64 tmp;
/* the first term */
i128->hi += x_u32 * y_u32;
/* the second term: sign-extend it only if x is negative */
tmp = x_u32 * y_l32;
if (x < 0)
i128->hi += INT64_AU32(tmp);
else
i128->hi += ((uint64) tmp) >> 32;
int128_add_uint64(i128, ((uint64) INT64_AL32(tmp)) << 32);
/* the third term: sign-extend it only if y is negative */
tmp = x_l32 * y_u32;
if (y < 0)
i128->hi += INT64_AU32(tmp);
else
i128->hi += ((uint64) tmp) >> 32;
int128_add_uint64(i128, ((uint64) INT64_AL32(tmp)) << 32);
/* the fourth term: always unsigned */
int128_add_uint64(i128, x_l32 * y_l32);
}
}
/*
* Compare two INT128 values, return -1, 0, or +1.
*/
static inline int
int128_compare(INT128 x, INT128 y)
{
if (x.hi < y.hi)
return -1;
if (x.hi > y.hi)
return 1;
if (x.lo < y.lo)
return -1;
if (x.lo > y.lo)
return 1;
return 0;
}
/*
* Widen int64 to INT128.
*/
static inline INT128
int64_to_int128(int64 v)
{
INT128 val;
val.lo = (uint64) v;
val.hi = (v < 0) ? -INT64CONST(1) : INT64CONST(0);
return val;
}
/*
* Convert INT128 to int64 (losing any high-order bits).
* This also works fine for casting down to uint64.
*/
static inline int64
int128_to_int64(INT128 val)
{
return (int64) val.lo;
}
#endif /* USE_NATIVE_INT128 */
#endif /* INT128_H */

37
db_include/common/ip.h Executable file
View File

@@ -0,0 +1,37 @@
/*-------------------------------------------------------------------------
*
* ip.h
* Definitions for IPv6-aware network access.
*
* These definitions are used by both frontend and backend code.
*
* Copyright (c) 2003-2021, PostgreSQL Global Development Group
*
* src/include/common/ip.h
*
*-------------------------------------------------------------------------
*/
#ifndef IP_H
#define IP_H
#include "getaddrinfo.h" /* pgrminclude ignore */
#include "libpq/pqcomm.h" /* pgrminclude ignore */
#ifdef HAVE_UNIX_SOCKETS
#define IS_AF_UNIX(fam) ((fam) == AF_UNIX)
#else
#define IS_AF_UNIX(fam) (0)
#endif
extern int pg_getaddrinfo_all(const char *hostname, const char *servname,
const struct addrinfo *hintp,
struct addrinfo **result);
extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai);
extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,
char *node, int nodelen,
char *service, int servicelen,
int flags);
#endif /* IP_H */

169
db_include/common/jsonapi.h Executable file
View File

@@ -0,0 +1,169 @@
/*-------------------------------------------------------------------------
*
* jsonapi.h
* Declarations for JSON API support.
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/jsonapi.h
*
*-------------------------------------------------------------------------
*/
#ifndef JSONAPI_H
#define JSONAPI_H
#include "lib/stringinfo.h"
typedef enum
{
JSON_TOKEN_INVALID,
JSON_TOKEN_STRING,
JSON_TOKEN_NUMBER,
JSON_TOKEN_OBJECT_START,
JSON_TOKEN_OBJECT_END,
JSON_TOKEN_ARRAY_START,
JSON_TOKEN_ARRAY_END,
JSON_TOKEN_COMMA,
JSON_TOKEN_COLON,
JSON_TOKEN_TRUE,
JSON_TOKEN_FALSE,
JSON_TOKEN_NULL,
JSON_TOKEN_END
} JsonTokenType;
typedef enum
{
JSON_SUCCESS,
JSON_ESCAPING_INVALID,
JSON_ESCAPING_REQUIRED,
JSON_EXPECTED_ARRAY_FIRST,
JSON_EXPECTED_ARRAY_NEXT,
JSON_EXPECTED_COLON,
JSON_EXPECTED_END,
JSON_EXPECTED_JSON,
JSON_EXPECTED_MORE,
JSON_EXPECTED_OBJECT_FIRST,
JSON_EXPECTED_OBJECT_NEXT,
JSON_EXPECTED_STRING,
JSON_INVALID_TOKEN,
JSON_UNICODE_CODE_POINT_ZERO,
JSON_UNICODE_ESCAPE_FORMAT,
JSON_UNICODE_HIGH_ESCAPE,
JSON_UNICODE_HIGH_SURROGATE,
JSON_UNICODE_LOW_SURROGATE
} JsonParseErrorType;
/*
* All the fields in this structure should be treated as read-only.
*
* If strval is not null, then it should contain the de-escaped value
* of the lexeme if it's a string. Otherwise most of these field names
* should be self-explanatory.
*
* line_number and line_start are principally for use by the parser's
* error reporting routines.
* token_terminator and prev_token_terminator point to the character
* AFTER the end of the token, i.e. where there would be a nul byte
* if we were using nul-terminated strings.
*/
typedef struct JsonLexContext
{
char *input;
int input_length;
int input_encoding;
char *token_start;
char *token_terminator;
char *prev_token_terminator;
JsonTokenType token_type;
int lex_level;
int line_number; /* line number, starting from 1 */
char *line_start; /* where that line starts within input */
StringInfo strval;
} JsonLexContext;
typedef void (*json_struct_action) (void *state);
typedef void (*json_ofield_action) (void *state, char *fname, bool isnull);
typedef void (*json_aelem_action) (void *state, bool isnull);
typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype);
/*
* Semantic Action structure for use in parsing json.
* Any of these actions can be NULL, in which case nothing is done at that
* point, Likewise, semstate can be NULL. Using an all-NULL structure amounts
* to doing a pure parse with no side-effects, and is therefore exactly
* what the json input routines do.
*
* The 'fname' and 'token' strings passed to these actions are palloc'd.
* They are not free'd or used further by the parser, so the action function
* is free to do what it wishes with them.
*/
typedef struct JsonSemAction
{
void *semstate;
json_struct_action object_start;
json_struct_action object_end;
json_struct_action array_start;
json_struct_action array_end;
json_ofield_action object_field_start;
json_ofield_action object_field_end;
json_aelem_action array_element_start;
json_aelem_action array_element_end;
json_scalar_action scalar;
} JsonSemAction;
/*
* pg_parse_json will parse the string in the lex calling the
* action functions in sem at the appropriate points. It is
* up to them to keep what state they need in semstate. If they
* need access to the state of the lexer, then its pointer
* should be passed to them as a member of whatever semstate
* points to. If the action pointers are NULL the parser
* does nothing and just continues.
*/
extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
JsonSemAction *sem);
/* the null action object used for pure validation */
extern JsonSemAction nullSemAction;
/*
* json_count_array_elements performs a fast secondary parse to determine the
* number of elements in passed array lex context. It should be called from an
* array_start action.
*
* The return value indicates whether any error occurred, while the number
* of elements is stored into *elements (but only if the return value is
* JSON_SUCCESS).
*/
extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
int *elements);
/*
* constructor for JsonLexContext, with or without strval element.
* If supplied, the strval element will contain a de-escaped version of
* the lexeme. However, doing this imposes a performance penalty, so
* it should be avoided if the de-escaped lexeme is not required.
*/
extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
int len,
int encoding,
bool need_escapes);
/* lex one token */
extern JsonParseErrorType json_lex(JsonLexContext *lex);
/* construct an error detail string for a json error */
extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex);
/*
* Utility function to check if a string is a valid JSON number.
*
* str argument does not need to be nul-terminated.
*/
extern bool IsValidJsonNumber(const char *str, int len);
#endif /* JSONAPI_H */

35
db_include/common/keywords.h Executable file
View File

@@ -0,0 +1,35 @@
/*-------------------------------------------------------------------------
*
* keywords.h
* PostgreSQL's list of SQL keywords
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/keywords.h
*
*-------------------------------------------------------------------------
*/
#ifndef KEYWORDS_H
#define KEYWORDS_H
#include "common/kwlookup.h"
/* Keyword categories --- should match lists in gram.y */
#define UNRESERVED_KEYWORD 0
#define COL_NAME_KEYWORD 1
#define TYPE_FUNC_NAME_KEYWORD 2
#define RESERVED_KEYWORD 3
#ifndef FRONTEND
extern PGDLLIMPORT const ScanKeywordList ScanKeywords;
extern PGDLLIMPORT const uint8 ScanKeywordCategories[];
extern PGDLLIMPORT const bool ScanKeywordBareLabel[];
#else
extern const ScanKeywordList ScanKeywords;
extern const uint8 ScanKeywordCategories[];
extern const bool ScanKeywordBareLabel[];
#endif
#endif /* KEYWORDS_H */

44
db_include/common/kwlookup.h Executable file
View File

@@ -0,0 +1,44 @@
/*-------------------------------------------------------------------------
*
* kwlookup.h
* Key word lookup for PostgreSQL
*
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/kwlookup.h
*
*-------------------------------------------------------------------------
*/
#ifndef KWLOOKUP_H
#define KWLOOKUP_H
/* Hash function used by ScanKeywordLookup */
typedef int (*ScanKeywordHashFunc) (const void *key, size_t keylen);
/*
* This struct contains the data needed by ScanKeywordLookup to perform a
* search within a set of keywords. The contents are typically generated by
* src/tools/gen_keywordlist.pl from a header containing PG_KEYWORD macros.
*/
typedef struct ScanKeywordList
{
const char *kw_string; /* all keywords in order, separated by \0 */
const uint16 *kw_offsets; /* offsets to the start of each keyword */
ScanKeywordHashFunc hash; /* perfect hash function for keywords */
int num_keywords; /* number of keywords */
int max_kw_len; /* length of longest keyword */
} ScanKeywordList;
extern int ScanKeywordLookup(const char *text, const ScanKeywordList *keywords);
/* Code that wants to retrieve the text of the N'th keyword should use this. */
static inline const char *
GetScanKeyword(int n, const ScanKeywordList *keywords)
{
return keywords->kw_string + keywords->kw_offsets[n];
}
#endif /* KWLOOKUP_H */

17
db_include/common/link-canary.h Executable file
View File

@@ -0,0 +1,17 @@
/*-------------------------------------------------------------------------
*
* link-canary.h
* Detect whether src/common functions came from frontend or backend.
*
* Copyright (c) 2018-2021, PostgreSQL Global Development Group
*
* src/include/common/link-canary.h
*
*-------------------------------------------------------------------------
*/
#ifndef LINK_CANARY_H
#define LINK_CANARY_H
extern bool pg_link_canary_is_frontend(void);
#endif /* LINK_CANARY_H */

96
db_include/common/logging.h Executable file
View File

@@ -0,0 +1,96 @@
/*-------------------------------------------------------------------------
* Logging framework for frontend programs
*
* Copyright (c) 2018-2021, PostgreSQL Global Development Group
*
* src/include/common/logging.h
*
*-------------------------------------------------------------------------
*/
#ifndef COMMON_LOGGING_H
#define COMMON_LOGGING_H
/*
* Log levels are informational only. They do not affect program flow.
*/
enum pg_log_level
{
/*
* Not initialized yet
*/
PG_LOG_NOTSET = 0,
/*
* Low level messages that are normally off by default.
*/
PG_LOG_DEBUG,
/*
* Any program messages that go to stderr, shown by default. (The
* program's normal output should go to stdout and not use the logging
* system.)
*/
PG_LOG_INFO,
/*
* Warnings and "almost" errors, depends on the program
*/
PG_LOG_WARNING,
/*
* Errors
*/
PG_LOG_ERROR,
/*
* Severe errors that cause program termination. (One-shot programs may
* chose to label even fatal errors as merely "errors". The distinction
* is up to the program.)
*/
PG_LOG_FATAL,
/*
* Turn all logging off.
*/
PG_LOG_OFF,
};
extern enum pg_log_level __pg_log_level;
/*
* Kind of a hack to be able to produce the psql output exactly as required by
* the regression tests.
*/
#define PG_LOG_FLAG_TERSE 1
void pg_logging_init(const char *argv0);
void pg_logging_config(int new_flags);
void pg_logging_set_level(enum pg_log_level new_level);
void pg_logging_increase_verbosity(void);
void pg_logging_set_pre_callback(void (*cb) (void));
void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno));
void pg_log_generic(enum pg_log_level level, const char *pg_restrict fmt,...) pg_attribute_printf(2, 3);
void pg_log_generic_v(enum pg_log_level level, const char *pg_restrict fmt, va_list ap) pg_attribute_printf(2, 0);
#define pg_log_fatal(...) do { \
if (likely(__pg_log_level <= PG_LOG_FATAL)) pg_log_generic(PG_LOG_FATAL, __VA_ARGS__); \
} while(0)
#define pg_log_error(...) do { \
if (likely(__pg_log_level <= PG_LOG_ERROR)) pg_log_generic(PG_LOG_ERROR, __VA_ARGS__); \
} while(0)
#define pg_log_warning(...) do { \
if (likely(__pg_log_level <= PG_LOG_WARNING)) pg_log_generic(PG_LOG_WARNING, __VA_ARGS__); \
} while(0)
#define pg_log_info(...) do { \
if (likely(__pg_log_level <= PG_LOG_INFO)) pg_log_generic(PG_LOG_INFO, __VA_ARGS__); \
} while(0)
#define pg_log_debug(...) do { \
if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) pg_log_generic(PG_LOG_DEBUG, __VA_ARGS__); \
} while(0)
#endif /* COMMON_LOGGING_H */

34
db_include/common/md5.h Executable file
View File

@@ -0,0 +1,34 @@
/*-------------------------------------------------------------------------
*
* md5.h
* Constants and common utilities related to MD5.
*
* These definitions are needed by both frontend and backend code to work
* with MD5-encrypted passwords.
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/md5.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_MD5_H
#define PG_MD5_H
/* Size of result generated by MD5 computation */
#define MD5_DIGEST_LENGTH 16
/* Block size for MD5 */
#define MD5_BLOCK_SIZE 64
/* password-related data */
#define MD5_PASSWD_CHARSET "0123456789abcdef"
#define MD5_PASSWD_LEN 35
/* Utilities common to all the MD5 implementations, as of md5_common.c */
extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum);
extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf);
extern bool pg_md5_encrypt(const char *passwd, const char *salt,
size_t salt_len, char *buf);
#endif /* PG_MD5_H */

49
db_include/common/openssl.h Executable file
View File

@@ -0,0 +1,49 @@
/*-------------------------------------------------------------------------
*
* openssl.h
* OpenSSL supporting functionality shared between frontend and backend
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/common/openssl.h
*
*-------------------------------------------------------------------------
*/
#ifndef COMMON_OPENSSL_H
#define COMMON_OPENSSL_H
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
/*
* OpenSSL doesn't provide any very nice way to identify the min/max
* protocol versions the library supports, so we fake it as best we can.
* Note in particular that this doesn't account for restrictions that
* might be specified in the installation's openssl.cnf.
*
* We disable SSLv3 and older in library setup, so TLSv1 is the oldest
* protocol version of interest.
*/
#define MIN_OPENSSL_TLS_VERSION "TLSv1"
#if defined(TLS1_3_VERSION)
#define MAX_OPENSSL_TLS_VERSION "TLSv1.3"
#elif defined(TLS1_2_VERSION)
#define MAX_OPENSSL_TLS_VERSION "TLSv1.2"
#elif defined(TLS1_1_VERSION)
#define MAX_OPENSSL_TLS_VERSION "TLSv1.1"
#else
#define MAX_OPENSSL_TLS_VERSION "TLSv1"
#endif
/* src/common/protocol_openssl.c */
#ifndef SSL_CTX_set_min_proto_version
extern int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
extern int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
#endif
#endif /* USE_OPENSSL */
#endif /* COMMON_OPENSSL_H */

View File

@@ -0,0 +1,93 @@
/* ----------
* pg_lzcompress.h -
*
* Definitions for the builtin LZ compressor
*
* src/include/common/pg_lzcompress.h
* ----------
*/
#ifndef _PG_LZCOMPRESS_H_
#define _PG_LZCOMPRESS_H_
/* ----------
* PGLZ_MAX_OUTPUT -
*
* Macro to compute the buffer size required by pglz_compress().
* We allow 4 bytes for overrun before detecting compression failure.
* ----------
*/
#define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + 4)
/* ----------
* PGLZ_Strategy -
*
* Some values that control the compression algorithm.
*
* min_input_size Minimum input data size to consider compression.
*
* max_input_size Maximum input data size to consider compression.
*
* min_comp_rate Minimum compression rate (0-99%) to require.
* Regardless of min_comp_rate, the output must be
* smaller than the input, else we don't store
* compressed.
*
* first_success_by Abandon compression if we find no compressible
* data within the first this-many bytes.
*
* match_size_good The initial GOOD match size when starting history
* lookup. When looking up the history to find a
* match that could be expressed as a tag, the
* algorithm does not always walk back entirely.
* A good match fast is usually better than the
* best possible one very late. For each iteration
* in the lookup, this value is lowered so the
* longer the lookup takes, the smaller matches
* are considered good.
*
* match_size_drop The percentage by which match_size_good is lowered
* after each history check. Allowed values are
* 0 (no change until end) to 100 (only check
* latest history entry at all).
* ----------
*/
typedef struct PGLZ_Strategy
{
int32 min_input_size;
int32 max_input_size;
int32 min_comp_rate;
int32 first_success_by;
int32 match_size_good;
int32 match_size_drop;
} PGLZ_Strategy;
/* ----------
* The standard strategies
*
* PGLZ_strategy_default Recommended default strategy for TOAST.
*
* PGLZ_strategy_always Try to compress inputs of any length.
* Fallback to uncompressed storage only if
* output would be larger than input.
* ----------
*/
extern const PGLZ_Strategy *const PGLZ_strategy_default;
extern const PGLZ_Strategy *const PGLZ_strategy_always;
/* ----------
* Global function declarations
* ----------
*/
extern int32 pglz_compress(const char *source, int32 slen, char *dest,
const PGLZ_Strategy *strategy);
extern int32 pglz_decompress(const char *source, int32 slen, char *dest,
int32 rawsize, bool check_complete);
extern int32 pglz_maximum_compressed_size(int32 rawsize,
int32 total_compressed_size);
#endif /* _PG_LZCOMPRESS_H_ */

90
db_include/common/relpath.h Executable file
View File

@@ -0,0 +1,90 @@
/*-------------------------------------------------------------------------
*
* relpath.h
* Declarations for GetRelationPath() and friends
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/relpath.h
*
*-------------------------------------------------------------------------
*/
#ifndef RELPATH_H
#define RELPATH_H
/*
* 'pgrminclude ignore' needed here because CppAsString2() does not throw
* an error if the symbol is not defined.
*/
#include "catalog/catversion.h" /* pgrminclude ignore */
/*
* Name of major-version-specific tablespace subdirectories
*/
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \
CppAsString2(CATALOG_VERSION_NO)
/* Characters to allow for an OID in a relation path */
#define OIDCHARS 10 /* max chars printed by %u */
/*
* Stuff for fork names.
*
* The physical storage of a relation consists of one or more forks.
* The main fork is always created, but in addition to that there can be
* additional forks for storing various metadata. ForkNumber is used when
* we need to refer to a specific fork in a relation.
*/
typedef enum ForkNumber
{
InvalidForkNumber = -1,
MAIN_FORKNUM = 0,
FSM_FORKNUM,
VISIBILITYMAP_FORKNUM,
INIT_FORKNUM
/*
* NOTE: if you add a new fork, change MAX_FORKNUM and possibly
* FORKNAMECHARS below, and update the forkNames array in
* src/common/relpath.c
*/
} ForkNumber;
#define MAX_FORKNUM INIT_FORKNUM
#define FORKNAMECHARS 4 /* max chars for a fork name */
extern const char *const forkNames[];
extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork);
/*
* Stuff for computing filesystem pathnames for relations.
*/
extern char *GetDatabasePath(Oid dbNode, Oid spcNode);
extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
int backendId, ForkNumber forkNumber);
/*
* Wrapper macros for GetRelationPath. Beware of multiple
* evaluation of the RelFileNode or RelFileNodeBackend argument!
*/
/* First argument is a RelFileNode */
#define relpathbackend(rnode, backend, forknum) \
GetRelationPath((rnode).dbNode, (rnode).spcNode, (rnode).relNode, \
backend, forknum)
/* First argument is a RelFileNode */
#define relpathperm(rnode, forknum) \
relpathbackend(rnode, InvalidBackendId, forknum)
/* First argument is a RelFileNodeBackend */
#define relpath(rnode, forknum) \
relpathbackend((rnode).node, (rnode).backend, forknum)
#endif /* RELPATH_H */

View File

@@ -0,0 +1,24 @@
/*
* restricted_token.h
* helper routine to ensure restricted token on Windows
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/restricted_token.h
*/
#ifndef COMMON_RESTRICTED_TOKEN_H
#define COMMON_RESTRICTED_TOKEN_H
/*
* On Windows make sure that we are running with a restricted token,
* On other platforms do nothing.
*/
void get_restricted_token(void);
#ifdef WIN32
/* Create a restricted token and execute the specified process with it. */
HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo);
#endif
#endif /* COMMON_RESTRICTED_TOKEN_H */

30
db_include/common/saslprep.h Executable file
View File

@@ -0,0 +1,30 @@
/*-------------------------------------------------------------------------
*
* saslprep.h
* SASLprep normalization, for SCRAM authentication
*
* These definitions are used by both frontend and backend code.
*
* Copyright (c) 2017-2021, PostgreSQL Global Development Group
*
* src/include/common/saslprep.h
*
*-------------------------------------------------------------------------
*/
#ifndef SASLPREP_H
#define SASLPREP_H
/*
* Return codes for pg_saslprep() function.
*/
typedef enum
{
SASLPREP_SUCCESS = 0,
SASLPREP_OOM = -1, /* out of memory (only in frontend) */
SASLPREP_INVALID_UTF8 = -2, /* input is not a valid UTF-8 string */
SASLPREP_PROHIBITED = -3 /* output would contain prohibited characters */
} pg_saslprep_rc;
extern pg_saslprep_rc pg_saslprep(const char *input, char **output);
#endif /* SASLPREP_H */

View File

@@ -0,0 +1,58 @@
/*-------------------------------------------------------------------------
*
* scram-common.h
* Declarations for helper functions used for SCRAM authentication
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/scram-common.h
*
*-------------------------------------------------------------------------
*/
#ifndef SCRAM_COMMON_H
#define SCRAM_COMMON_H
#include "common/cryptohash.h"
#include "common/sha2.h"
/* Name of SCRAM mechanisms per IANA */
#define SCRAM_SHA_256_NAME "SCRAM-SHA-256"
#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */
/* Length of SCRAM keys (client and server) */
#define SCRAM_KEY_LEN PG_SHA256_DIGEST_LENGTH
/* length of HMAC */
#define SHA256_HMAC_B PG_SHA256_BLOCK_LENGTH
/*
* Size of random nonce generated in the authentication exchange. This
* is in "raw" number of bytes, the actual nonces sent over the wire are
* encoded using only ASCII-printable characters.
*/
#define SCRAM_RAW_NONCE_LEN 18
/*
* Length of salt when generating new secrets, in bytes. (It will be stored
* and sent over the wire encoded in Base64.) 16 bytes is what the example in
* RFC 7677 uses.
*/
#define SCRAM_DEFAULT_SALT_LEN 16
/*
* Default number of iterations when generating secret. Should be at least
* 4096 per RFC 7677.
*/
#define SCRAM_DEFAULT_ITERATIONS 4096
extern int scram_SaltedPassword(const char *password, const char *salt,
int saltlen, int iterations, uint8 *result);
extern int scram_H(const uint8 *str, int len, uint8 *result);
extern int scram_ClientKey(const uint8 *salted_password, uint8 *result);
extern int scram_ServerKey(const uint8 *salted_password, uint8 *result);
extern char *scram_build_secret(const char *salt, int saltlen, int iterations,
const char *password);
#endif /* SCRAM_COMMON_H */

21
db_include/common/sha1.h Executable file
View File

@@ -0,0 +1,21 @@
/*-------------------------------------------------------------------------
*
* sha1.h
* Constants related to SHA1.
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/sha1.h
*
*-------------------------------------------------------------------------
*/
#ifndef PG_SHA1_H
#define PG_SHA1_H
/* Size of result generated by SHA1 computation */
#define SHA1_DIGEST_LENGTH 20
/* Block size for SHA1 */
#define SHA1_BLOCK_SIZE 64
#endif /* PG_SHA1_H */

32
db_include/common/sha2.h Executable file
View File

@@ -0,0 +1,32 @@
/*-------------------------------------------------------------------------
*
* sha2.h
* Constants related to SHA224, 256, 384 AND 512.
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/common/sha2.h
*
*-------------------------------------------------------------------------
*/
#ifndef _PG_SHA2_H_
#define _PG_SHA2_H_
/*** SHA224/256/384/512 Various Length Definitions ***********************/
#define PG_SHA224_BLOCK_LENGTH 64
#define PG_SHA224_DIGEST_LENGTH 28
#define PG_SHA224_DIGEST_STRING_LENGTH (PG_SHA224_DIGEST_LENGTH * 2 + 1)
#define PG_SHA256_BLOCK_LENGTH 64
#define PG_SHA256_DIGEST_LENGTH 32
#define PG_SHA256_DIGEST_STRING_LENGTH (PG_SHA256_DIGEST_LENGTH * 2 + 1)
#define PG_SHA384_BLOCK_LENGTH 128
#define PG_SHA384_DIGEST_LENGTH 48
#define PG_SHA384_DIGEST_STRING_LENGTH (PG_SHA384_DIGEST_LENGTH * 2 + 1)
#define PG_SHA512_BLOCK_LENGTH 128
#define PG_SHA512_DIGEST_LENGTH 64
#define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1)
#endif /* _PG_SHA2_H_ */

View File

@@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------
*
* Ryu floating-point output.
*
* Portions Copyright (c) 2018-2021, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/include/common/shortest_dec.h
*
* This is a modification of code taken from github.com/ulfjack/ryu under the
* terms of the Boost license (not the Apache license). The original copyright
* notice follows:
*
* Copyright 2018 Ulf Adams
*
* The contents of this file may be used under the terms of the Apache
* License, Version 2.0.
*
* (See accompanying file LICENSE-Apache or copy at
* http://www.apache.org/licenses/LICENSE-2.0)
*
* Alternatively, the contents of this file may be used under the terms of the
* Boost Software License, Version 1.0.
*
* (See accompanying file LICENSE-Boost or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Unless required by applicable law or agreed to in writing, this software is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.
*
*---------------------------------------------------------------------------
*/
#ifndef SHORTEST_DEC_H
#define SHORTEST_DEC_H
/*----
* The length of 25 comes from:
*
* Case 1: -9.9999999999999999e-299 = 24 bytes, plus 1 for null
*
* Case 2: -0.00099999999999999999 = 23 bytes, plus 1 for null
*/
#define DOUBLE_SHORTEST_DECIMAL_LEN 25
int double_to_shortest_decimal_bufn(double f, char *result);
int double_to_shortest_decimal_buf(double f, char *result);
char *double_to_shortest_decimal(double f);
/*
* The length of 16 comes from:
*
* Case 1: -9.99999999e+29 = 15 bytes, plus 1 for null
*
* Case 2: -0.000999999999 = 15 bytes, plus 1 for null
*/
#define FLOAT_SHORTEST_DECIMAL_LEN 16
int float_to_shortest_decimal_bufn(float f, char *result);
int float_to_shortest_decimal_buf(float f, char *result);
char *float_to_shortest_decimal(float f);
#endif /* SHORTEST_DEC_H */

31
db_include/common/string.h Executable file
View File

@@ -0,0 +1,31 @@
/*
* string.h
* string handling helpers
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/common/string.h
*/
#ifndef COMMON_STRING_H
#define COMMON_STRING_H
struct StringInfoData; /* avoid including stringinfo.h here */
/* functions in src/common/string.c */
extern bool pg_str_endswith(const char *str, const char *end);
extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr,
int base);
extern void pg_clean_ascii(char *str);
extern int pg_strip_crlf(char *str);
extern bool pg_is_ascii(const char *str);
/* functions in src/common/pg_get_line.c */
extern char *pg_get_line(FILE *stream);
extern bool pg_get_line_buf(FILE *stream, struct StringInfoData *buf);
extern bool pg_get_line_append(FILE *stream, struct StringInfoData *buf);
/* functions in src/common/sprompt.c */
extern char *simple_prompt(const char *prompt, bool echo);
#endif /* COMMON_STRING_H */

View File

@@ -0,0 +1,196 @@
/* generated by src/common/unicode/generate-unicode_combining_table.pl, do not edit */
static const struct mbinterval combining[] = {
{0x0300, 0x036F},
{0x0483, 0x0489},
{0x0591, 0x05BD},
{0x05BF, 0x05BF},
{0x05C1, 0x05C2},
{0x05C4, 0x05C5},
{0x05C7, 0x05C7},
{0x0610, 0x061A},
{0x064B, 0x065F},
{0x0670, 0x0670},
{0x06D6, 0x06DC},
{0x06DF, 0x06E4},
{0x06E7, 0x06E8},
{0x06EA, 0x06ED},
{0x0711, 0x0711},
{0x0730, 0x074A},
{0x07A6, 0x07B0},
{0x07EB, 0x07F3},
{0x07FD, 0x07FD},
{0x0816, 0x0819},
{0x081B, 0x0823},
{0x0825, 0x0827},
{0x0829, 0x082D},
{0x0859, 0x085B},
{0x08D3, 0x08E1},
{0x08E3, 0x0902},
{0x093A, 0x093A},
{0x093C, 0x093C},
{0x0941, 0x0948},
{0x094D, 0x094D},
{0x0951, 0x0957},
{0x0962, 0x0963},
{0x0981, 0x0981},
{0x09BC, 0x09BC},
{0x09C1, 0x09C4},
{0x09CD, 0x09CD},
{0x09E2, 0x09E3},
{0x09FE, 0x0A02},
{0x0A3C, 0x0A3C},
{0x0A41, 0x0A51},
{0x0A70, 0x0A71},
{0x0A75, 0x0A75},
{0x0A81, 0x0A82},
{0x0ABC, 0x0ABC},
{0x0AC1, 0x0AC8},
{0x0ACD, 0x0ACD},
{0x0AE2, 0x0AE3},
{0x0AFA, 0x0B01},
{0x0B3C, 0x0B3C},
{0x0B3F, 0x0B3F},
{0x0B41, 0x0B44},
{0x0B4D, 0x0B56},
{0x0B62, 0x0B63},
{0x0B82, 0x0B82},
{0x0BC0, 0x0BC0},
{0x0BCD, 0x0BCD},
{0x0C00, 0x0C00},
{0x0C04, 0x0C04},
{0x0C3E, 0x0C40},
{0x0C46, 0x0C56},
{0x0C62, 0x0C63},
{0x0C81, 0x0C81},
{0x0CBC, 0x0CBC},
{0x0CBF, 0x0CBF},
{0x0CC6, 0x0CC6},
{0x0CCC, 0x0CCD},
{0x0CE2, 0x0CE3},
{0x0D00, 0x0D01},
{0x0D3B, 0x0D3C},
{0x0D41, 0x0D44},
{0x0D4D, 0x0D4D},
{0x0D62, 0x0D63},
{0x0D81, 0x0D81},
{0x0DCA, 0x0DCA},
{0x0DD2, 0x0DD6},
{0x0E31, 0x0E31},
{0x0E34, 0x0E3A},
{0x0E47, 0x0E4E},
{0x0EB1, 0x0EB1},
{0x0EB4, 0x0EBC},
{0x0EC8, 0x0ECD},
{0x0F18, 0x0F19},
{0x0F35, 0x0F35},
{0x0F37, 0x0F37},
{0x0F39, 0x0F39},
{0x0F71, 0x0F7E},
{0x0F80, 0x0F84},
{0x0F86, 0x0F87},
{0x0F8D, 0x0FBC},
{0x0FC6, 0x0FC6},
{0x102D, 0x1030},
{0x1032, 0x1037},
{0x1039, 0x103A},
{0x103D, 0x103E},
{0x1058, 0x1059},
{0x105E, 0x1060},
{0x1071, 0x1074},
{0x1082, 0x1082},
{0x1085, 0x1086},
{0x108D, 0x108D},
{0x109D, 0x109D},
{0x135D, 0x135F},
{0x1712, 0x1714},
{0x1732, 0x1734},
{0x1752, 0x1753},
{0x1772, 0x1773},
{0x17B4, 0x17B5},
{0x17B7, 0x17BD},
{0x17C6, 0x17C6},
{0x17C9, 0x17D3},
{0x17DD, 0x17DD},
{0x180B, 0x180D},
{0x1885, 0x1886},
{0x18A9, 0x18A9},
{0x1920, 0x1922},
{0x1927, 0x1928},
{0x1932, 0x1932},
{0x1939, 0x193B},
{0x1A17, 0x1A18},
{0x1A1B, 0x1A1B},
{0x1A56, 0x1A56},
{0x1A58, 0x1A60},
{0x1A62, 0x1A62},
{0x1A65, 0x1A6C},
{0x1A73, 0x1A7F},
{0x1AB0, 0x1B03},
{0x1B34, 0x1B34},
{0x1B36, 0x1B3A},
{0x1B3C, 0x1B3C},
{0x1B42, 0x1B42},
{0x1B6B, 0x1B73},
{0x1B80, 0x1B81},
{0x1BA2, 0x1BA5},
{0x1BA8, 0x1BA9},
{0x1BAB, 0x1BAD},
{0x1BE6, 0x1BE6},
{0x1BE8, 0x1BE9},
{0x1BED, 0x1BED},
{0x1BEF, 0x1BF1},
{0x1C2C, 0x1C33},
{0x1C36, 0x1C37},
{0x1CD0, 0x1CD2},
{0x1CD4, 0x1CE0},
{0x1CE2, 0x1CE8},
{0x1CED, 0x1CED},
{0x1CF4, 0x1CF4},
{0x1CF8, 0x1CF9},
{0x1DC0, 0x1DFF},
{0x20D0, 0x20F0},
{0x2CEF, 0x2CF1},
{0x2D7F, 0x2D7F},
{0x2DE0, 0x2DFF},
{0x302A, 0x302D},
{0x3099, 0x309A},
{0xA66F, 0xA672},
{0xA674, 0xA67D},
{0xA69E, 0xA69F},
{0xA6F0, 0xA6F1},
{0xA802, 0xA802},
{0xA806, 0xA806},
{0xA80B, 0xA80B},
{0xA825, 0xA826},
{0xA82C, 0xA82C},
{0xA8C4, 0xA8C5},
{0xA8E0, 0xA8F1},
{0xA8FF, 0xA8FF},
{0xA926, 0xA92D},
{0xA947, 0xA951},
{0xA980, 0xA982},
{0xA9B3, 0xA9B3},
{0xA9B6, 0xA9B9},
{0xA9BC, 0xA9BD},
{0xA9E5, 0xA9E5},
{0xAA29, 0xAA2E},
{0xAA31, 0xAA32},
{0xAA35, 0xAA36},
{0xAA43, 0xAA43},
{0xAA4C, 0xAA4C},
{0xAA7C, 0xAA7C},
{0xAAB0, 0xAAB0},
{0xAAB2, 0xAAB4},
{0xAAB7, 0xAAB8},
{0xAABE, 0xAABF},
{0xAAC1, 0xAAC1},
{0xAAEC, 0xAAED},
{0xAAF6, 0xAAF6},
{0xABE5, 0xABE5},
{0xABE8, 0xABE8},
{0xABED, 0xABED},
{0xFB1E, 0xFB1E},
{0xFE00, 0xFE0F},
{0xFE20, 0xFE2F},
};

View File

@@ -0,0 +1,39 @@
/*-------------------------------------------------------------------------
*
* unicode_norm.h
* Routines for normalizing Unicode strings
*
* These definitions are used by both frontend and backend code.
*
* Copyright (c) 2017-2021, PostgreSQL Global Development Group
*
* src/include/common/unicode_norm.h
*
*-------------------------------------------------------------------------
*/
#ifndef UNICODE_NORM_H
#define UNICODE_NORM_H
#include "mb/pg_wchar.h"
typedef enum
{
UNICODE_NFC = 0,
UNICODE_NFD = 1,
UNICODE_NFKC = 2,
UNICODE_NFKD = 3,
} UnicodeNormalizationForm;
/* see UAX #15 */
typedef enum
{
UNICODE_NORM_QC_NO = 0,
UNICODE_NORM_QC_YES = 1,
UNICODE_NORM_QC_MAYBE = -1,
} UnicodeNormalizationQC;
extern pg_wchar *unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input);
extern UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input);
#endif /* UNICODE_NORM_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

15
db_include/common/username.h Executable file
View File

@@ -0,0 +1,15 @@
/*
* username.h
* lookup effective username
*
* Copyright (c) 2003-2021, PostgreSQL Global Development Group
*
* src/include/common/username.h
*/
#ifndef USERNAME_H
#define USERNAME_H
extern const char *get_user_name(char **errstr);
extern const char *get_user_name_or_exit(const char *progname);
#endif /* USERNAME_H */