diff options
Diffstat (limited to 'src/common/archive.c')
-rw-r--r-- | src/common/archive.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/common/archive.c b/src/common/archive.c new file mode 100644 index 0000000..a94e4d0 --- /dev/null +++ b/src/common/archive.c @@ -0,0 +1,121 @@ +/*------------------------------------------------------------------------- + * + * archive.c + * Common WAL archive routines + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/common/archive.c + * + *------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include "common/archive.h" +#include "lib/stringinfo.h" + +/* + * BuildRestoreCommand + * + * Builds a restore command to retrieve a file from WAL archives, replacing + * the supported aliases with values supplied by the caller as defined by + * the GUC parameter restore_command: xlogpath for %p, xlogfname for %f and + * lastRestartPointFname for %r. + * + * The result is a palloc'd string for the restore command built. The + * caller is responsible for freeing it. If any of the required arguments + * is NULL and that the corresponding alias is found in the command given + * by the caller, then NULL is returned. + */ +char * +BuildRestoreCommand(const char *restoreCommand, + const char *xlogpath, + const char *xlogfname, + const char *lastRestartPointFname) +{ + StringInfoData result; + const char *sp; + + /* + * Build the command to be executed. + */ + initStringInfo(&result); + + for (sp = restoreCommand; *sp; sp++) + { + if (*sp == '%') + { + switch (sp[1]) + { + case 'p': + { + char *nativePath; + + /* %p: relative path of target file */ + if (xlogpath == NULL) + { + pfree(result.data); + return NULL; + } + sp++; + + /* + * This needs to use a placeholder to not modify the + * input with the conversion done via + * make_native_path(). + */ + nativePath = pstrdup(xlogpath); + make_native_path(nativePath); + appendStringInfoString(&result, + nativePath); + pfree(nativePath); + break; + } + case 'f': + /* %f: filename of desired file */ + if (xlogfname == NULL) + { + pfree(result.data); + return NULL; + } + sp++; + appendStringInfoString(&result, xlogfname); + break; + case 'r': + /* %r: filename of last restartpoint */ + if (lastRestartPointFname == NULL) + { + pfree(result.data); + return NULL; + } + sp++; + appendStringInfoString(&result, + lastRestartPointFname); + break; + case '%': + /* convert %% to a single % */ + sp++; + appendStringInfoChar(&result, *sp); + break; + default: + /* otherwise treat the % as not special */ + appendStringInfoChar(&result, *sp); + break; + } + } + else + { + appendStringInfoChar(&result, *sp); + } + } + + return result.data; +} |