PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
astreamer_file.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include "common/file_perm.h"
#include "common/logging.h"
#include "fe_utils/astreamer.h"
Include dependency graph for astreamer_file.c:

Go to the source code of this file.

Data Structures

struct  astreamer_plain_writer
 
struct  astreamer_extractor
 

Typedefs

typedef struct astreamer_plain_writer astreamer_plain_writer
 
typedef struct astreamer_extractor astreamer_extractor
 

Functions

static void astreamer_plain_writer_content (astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
 
static void astreamer_plain_writer_finalize (astreamer *streamer)
 
static void astreamer_plain_writer_free (astreamer *streamer)
 
static void astreamer_extractor_content (astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
 
static void astreamer_extractor_finalize (astreamer *streamer)
 
static void astreamer_extractor_free (astreamer *streamer)
 
static void extract_directory (const char *filename, mode_t mode)
 
static void extract_link (const char *filename, const char *linktarget)
 
static FILE * create_file_for_extract (const char *filename, mode_t mode)
 
astreamerastreamer_plain_writer_new (char *pathname, FILE *file)
 
astreamerastreamer_extractor_new (const char *basepath, const char *(*link_map)(const char *), void(*report_output_file)(const char *))
 
static bool should_allow_existing_directory (const char *pathname)
 

Variables

static const astreamer_ops astreamer_plain_writer_ops
 
static const astreamer_ops astreamer_extractor_ops
 

Typedef Documentation

◆ astreamer_extractor

◆ astreamer_plain_writer

Function Documentation

◆ astreamer_extractor_content()

static void astreamer_extractor_content ( astreamer streamer,
astreamer_member member,
const char *  data,
int  len,
astreamer_archive_context  context 
)
static

Definition at line 206 of file astreamer_file.c.

209 {
210  astreamer_extractor *mystreamer = (astreamer_extractor *) streamer;
211  int fnamelen;
212 
213  Assert(member != NULL || context == ASTREAMER_ARCHIVE_TRAILER);
215 
216  switch (context)
217  {
219  Assert(mystreamer->file == NULL);
220 
221  /* Prepend basepath. */
222  snprintf(mystreamer->filename, sizeof(mystreamer->filename),
223  "%s/%s", mystreamer->basepath, member->pathname);
224 
225  /* Remove any trailing slash. */
226  fnamelen = strlen(mystreamer->filename);
227  if (mystreamer->filename[fnamelen - 1] == '/')
228  mystreamer->filename[fnamelen - 1] = '\0';
229 
230  /* Dispatch based on file type. */
231  if (member->is_directory)
232  extract_directory(mystreamer->filename, member->mode);
233  else if (member->is_link)
234  {
235  const char *linktarget = member->linktarget;
236 
237  if (mystreamer->link_map)
238  linktarget = mystreamer->link_map(linktarget);
239  extract_link(mystreamer->filename, linktarget);
240  }
241  else
242  mystreamer->file =
243  create_file_for_extract(mystreamer->filename,
244  member->mode);
245 
246  /* Report output file change. */
247  if (mystreamer->report_output_file)
248  mystreamer->report_output_file(mystreamer->filename);
249  break;
250 
252  if (mystreamer->file == NULL)
253  break;
254 
255  errno = 0;
256  if (len > 0 && fwrite(data, len, 1, mystreamer->file) != 1)
257  {
258  /* if write didn't set errno, assume problem is no disk space */
259  if (errno == 0)
260  errno = ENOSPC;
261  pg_fatal("could not write to file \"%s\": %m",
262  mystreamer->filename);
263  }
264  break;
265 
267  if (mystreamer->file == NULL)
268  break;
269  fclose(mystreamer->file);
270  mystreamer->file = NULL;
271  break;
272 
274  break;
275 
276  default:
277  /* Shouldn't happen. */
278  pg_fatal("unexpected state while extracting archive");
279  }
280 }
@ ASTREAMER_MEMBER_HEADER
Definition: astreamer.h:65
@ ASTREAMER_MEMBER_CONTENTS
Definition: astreamer.h:66
@ ASTREAMER_MEMBER_TRAILER
Definition: astreamer.h:67
@ ASTREAMER_ARCHIVE_TRAILER
Definition: astreamer.h:68
@ ASTREAMER_UNKNOWN
Definition: astreamer.h:64
static void extract_directory(const char *filename, mode_t mode)
static FILE * create_file_for_extract(const char *filename, mode_t mode)
static void extract_link(const char *filename, const char *linktarget)
#define Assert(condition)
Definition: c.h:863
#define pg_fatal(...)
const void size_t len
const void * data
#define snprintf
Definition: port.h:238
tree context
Definition: radixtree.h:1835
void(* report_output_file)(const char *)
char filename[MAXPGPATH]
const char *(* link_map)(const char *)
char linktarget[MAXPGPATH]
Definition: astreamer.h:88
char pathname[MAXPGPATH]
Definition: astreamer.h:81

References Assert, ASTREAMER_ARCHIVE_TRAILER, ASTREAMER_MEMBER_CONTENTS, ASTREAMER_MEMBER_HEADER, ASTREAMER_MEMBER_TRAILER, ASTREAMER_UNKNOWN, astreamer_extractor::basepath, context, create_file_for_extract(), data, extract_directory(), extract_link(), astreamer_extractor::file, astreamer_extractor::filename, astreamer_member::is_directory, astreamer_member::is_link, len, astreamer_extractor::link_map, astreamer_member::linktarget, astreamer_member::mode, astreamer_member::pathname, pg_fatal, astreamer_extractor::report_output_file, and snprintf.

◆ astreamer_extractor_finalize()

static void astreamer_extractor_finalize ( astreamer streamer)
static

Definition at line 381 of file astreamer_file.c.

382 {
384  = (astreamer_extractor *) streamer;
385 
386  Assert(mystreamer->file == NULL);
387 }
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:197

References Assert, and PG_USED_FOR_ASSERTS_ONLY.

◆ astreamer_extractor_free()

static void astreamer_extractor_free ( astreamer streamer)
static

Definition at line 393 of file astreamer_file.c.

394 {
395  astreamer_extractor *mystreamer = (astreamer_extractor *) streamer;
396 
397  pfree(mystreamer->basepath);
398  pfree(mystreamer);
399 }
void pfree(void *pointer)
Definition: mcxt.c:1521

References astreamer_extractor::basepath, and pfree().

◆ astreamer_extractor_new()

astreamer* astreamer_extractor_new ( const char *  basepath,
const char *(*)(const char *)  link_map,
void(*)(const char *)  report_output_file 
)

Definition at line 186 of file astreamer_file.c.

189 {
190  astreamer_extractor *streamer;
191 
192  streamer = palloc0(sizeof(astreamer_extractor));
193  *((const astreamer_ops **) &streamer->base.bbs_ops) =
195  streamer->basepath = pstrdup(basepath);
196  streamer->link_map = link_map;
197  streamer->report_output_file = report_output_file;
198 
199  return &streamer->base;
200 }
static const astreamer_ops astreamer_extractor_ops
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void * palloc0(Size size)
Definition: mcxt.c:1347
const astreamer_ops * bbs_ops
Definition: astreamer.h:109

References astreamer_extractor_ops, astreamer_extractor::base, astreamer_extractor::basepath, astreamer::bbs_ops, astreamer_extractor::link_map, palloc0(), pstrdup(), and astreamer_extractor::report_output_file.

Referenced by CreateBackupStreamer().

◆ astreamer_plain_writer_content()

static void astreamer_plain_writer_content ( astreamer streamer,
astreamer_member member,
const char *  data,
int  len,
astreamer_archive_context  context 
)
static

Definition at line 107 of file astreamer_file.c.

110 {
111  astreamer_plain_writer *mystreamer;
112 
113  mystreamer = (astreamer_plain_writer *) streamer;
114 
115  if (len == 0)
116  return;
117 
118  errno = 0;
119  if (fwrite(data, len, 1, mystreamer->file) != 1)
120  {
121  /* if write didn't set errno, assume problem is no disk space */
122  if (errno == 0)
123  errno = ENOSPC;
124  pg_fatal("could not write to file \"%s\": %m",
125  mystreamer->pathname);
126  }
127 }

References data, astreamer_plain_writer::file, len, astreamer_plain_writer::pathname, and pg_fatal.

◆ astreamer_plain_writer_finalize()

static void astreamer_plain_writer_finalize ( astreamer streamer)
static

Definition at line 134 of file astreamer_file.c.

135 {
136  astreamer_plain_writer *mystreamer;
137 
138  mystreamer = (astreamer_plain_writer *) streamer;
139 
140  if (mystreamer->should_close_file && fclose(mystreamer->file) != 0)
141  pg_fatal("could not close file \"%s\": %m",
142  mystreamer->pathname);
143 
144  mystreamer->file = NULL;
145  mystreamer->should_close_file = false;
146 }

References astreamer_plain_writer::file, astreamer_plain_writer::pathname, pg_fatal, and astreamer_plain_writer::should_close_file.

◆ astreamer_plain_writer_free()

static void astreamer_plain_writer_free ( astreamer streamer)
static

Definition at line 152 of file astreamer_file.c.

153 {
154  astreamer_plain_writer *mystreamer;
155 
156  mystreamer = (astreamer_plain_writer *) streamer;
157 
158  Assert(!mystreamer->should_close_file);
159  Assert(mystreamer->base.bbs_next == NULL);
160 
161  pfree(mystreamer->pathname);
162  pfree(mystreamer);
163 }
astreamer * bbs_next
Definition: astreamer.h:110

References Assert, astreamer_plain_writer::base, astreamer::bbs_next, astreamer_plain_writer::pathname, pfree(), and astreamer_plain_writer::should_close_file.

◆ astreamer_plain_writer_new()

astreamer* astreamer_plain_writer_new ( char *  pathname,
FILE *  file 
)

Definition at line 81 of file astreamer_file.c.

82 {
83  astreamer_plain_writer *streamer;
84 
85  streamer = palloc0(sizeof(astreamer_plain_writer));
86  *((const astreamer_ops **) &streamer->base.bbs_ops) =
88 
89  streamer->pathname = pstrdup(pathname);
90  streamer->file = file;
91 
92  if (file == NULL)
93  {
94  streamer->file = fopen(pathname, "wb");
95  if (streamer->file == NULL)
96  pg_fatal("could not create file \"%s\": %m", pathname);
97  streamer->should_close_file = true;
98  }
99 
100  return &streamer->base;
101 }
static const astreamer_ops astreamer_plain_writer_ops

References astreamer_plain_writer_ops, astreamer_plain_writer::base, astreamer::bbs_ops, astreamer_plain_writer::file, palloc0(), astreamer_plain_writer::pathname, pg_fatal, pstrdup(), and astreamer_plain_writer::should_close_file.

Referenced by CreateBackupStreamer().

◆ create_file_for_extract()

static FILE * create_file_for_extract ( const char *  filename,
mode_t  mode 
)
static

Definition at line 358 of file astreamer_file.c.

359 {
360  FILE *file;
361 
362  file = fopen(filename, "wb");
363  if (file == NULL)
364  pg_fatal("could not create file \"%s\": %m", filename);
365 
366 #ifndef WIN32
367  if (chmod(filename, mode))
368  pg_fatal("could not set permissions on file \"%s\": %m",
369  filename);
370 #endif
371 
372  return file;
373 }
static PgChecksumMode mode
Definition: pg_checksums.c:55
static char * filename
Definition: pg_dumpall.c:119

References filename, mode, and pg_fatal.

Referenced by astreamer_extractor_content().

◆ extract_directory()

static void extract_directory ( const char *  filename,
mode_t  mode 
)
static

Definition at line 320 of file astreamer_file.c.

321 {
322  if (mkdir(filename, pg_dir_create_mode) != 0 &&
323  (errno != EEXIST || !should_allow_existing_directory(filename)))
324  pg_fatal("could not create directory \"%s\": %m",
325  filename);
326 
327 #ifndef WIN32
328  if (chmod(filename, mode))
329  pg_fatal("could not set permissions on directory \"%s\": %m",
330  filename);
331 #endif
332 }
static bool should_allow_existing_directory(const char *pathname)
int pg_dir_create_mode
Definition: file_perm.c:18
#define mkdir(a, b)
Definition: win32_port.h:80

References filename, mkdir, mode, pg_dir_create_mode, pg_fatal, and should_allow_existing_directory().

Referenced by astreamer_extractor_content().

◆ extract_link()

static void extract_link ( const char *  filename,
const char *  linktarget 
)
static

Definition at line 345 of file astreamer_file.c.

346 {
347  if (symlink(linktarget, filename) != 0)
348  pg_fatal("could not create symbolic link from \"%s\" to \"%s\": %m",
349  filename, linktarget);
350 }
#define symlink(oldpath, newpath)
Definition: win32_port.h:235

References filename, pg_fatal, and symlink.

Referenced by astreamer_extractor_content().

◆ should_allow_existing_directory()

static bool should_allow_existing_directory ( const char *  pathname)
static

Definition at line 295 of file astreamer_file.c.

296 {
297  const char *filename = last_dir_separator(pathname) + 1;
298 
299  if (strcmp(filename, "pg_wal") == 0 ||
300  strcmp(filename, "pg_xlog") == 0 ||
301  strcmp(filename, "archive_status") == 0 ||
302  strcmp(filename, "summaries") == 0 ||
303  strcmp(filename, "pg_tblspc") == 0)
304  return true;
305 
306  if (strspn(filename, "0123456789") == strlen(filename))
307  {
308  const char *pg_tblspc = strstr(pathname, "/pg_tblspc/");
309 
310  return pg_tblspc != NULL && pg_tblspc + 11 == filename;
311  }
312 
313  return false;
314 }
char * last_dir_separator(const char *filename)
Definition: path.c:140

References filename, and last_dir_separator().

Referenced by extract_directory().

Variable Documentation

◆ astreamer_extractor_ops

const astreamer_ops astreamer_extractor_ops
static
Initial value:
= {
}
static void astreamer_extractor_finalize(astreamer *streamer)
static void astreamer_extractor_free(astreamer *streamer)
static void astreamer_extractor_content(astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)

Definition at line 65 of file astreamer_file.c.

Referenced by astreamer_extractor_new().

◆ astreamer_plain_writer_ops

const astreamer_ops astreamer_plain_writer_ops
static
Initial value:
= {
}
static void astreamer_plain_writer_content(astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
static void astreamer_plain_writer_finalize(astreamer *streamer)
static void astreamer_plain_writer_free(astreamer *streamer)

Definition at line 49 of file astreamer_file.c.

Referenced by astreamer_plain_writer_new().