PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
initdb.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * initdb --- initialize a PostgreSQL installation
4  *
5  * initdb creates (initializes) a PostgreSQL database cluster (site,
6  * instance, installation, whatever). A database cluster is a
7  * collection of PostgreSQL databases all managed by the same server.
8  *
9  * To create the database cluster, we create the directory that contains
10  * all its data, create the files that hold the global tables, create
11  * a few other control files for it, and create three databases: the
12  * template databases "template0" and "template1", and a default user
13  * database "postgres".
14  *
15  * The template databases are ordinary PostgreSQL databases. template0
16  * is never supposed to change after initdb, whereas template1 can be
17  * changed to add site-local standard data. Either one can be copied
18  * to produce a new database.
19  *
20  * For largely-historical reasons, the template1 database is the one built
21  * by the basic bootstrap process. After it is complete, template0 and
22  * the default database, postgres, are made just by copying template1.
23  *
24  * To create template1, we run the postgres (backend) program in bootstrap
25  * mode and feed it data from the postgres.bki library file. After this
26  * initial bootstrap phase, some additional stuff is created by normal
27  * SQL commands fed to a standalone backend. Some of those commands are
28  * just embedded into this program (yeah, it's ugly), but larger chunks
29  * are taken from script files.
30  *
31  *
32  * Note:
33  * The program has some memory leakage - it isn't worth cleaning it up.
34  *
35  * This is a C implementation of the previous shell script for setting up a
36  * PostgreSQL cluster location, and should be highly compatible with it.
37  * author of C translation: Andrew Dunstan mailto:andrew@dunslane.net
38  *
39  * This code is released under the terms of the PostgreSQL License.
40  *
41  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
42  * Portions Copyright (c) 1994, Regents of the University of California
43  *
44  * src/bin/initdb/initdb.c
45  *
46  *-------------------------------------------------------------------------
47  */
48 
49 #include "postgres_fe.h"
50 
51 #include <dirent.h>
52 #include <fcntl.h>
53 #include <sys/stat.h>
54 #include <unistd.h>
55 #include <locale.h>
56 #include <signal.h>
57 #include <time.h>
58 
59 #ifdef HAVE_SHM_OPEN
60 #include "sys/mman.h"
61 #endif
62 
63 #include "catalog/catalog.h"
65 #include "common/username.h"
66 #include "mb/pg_wchar.h"
67 #include "getaddrinfo.h"
68 #include "getopt_long.h"
69 #include "miscadmin.h"
70 
71 /* Ideally this would be in a .h file, but it hardly seems worth the trouble */
72 extern const char *select_default_timezone(const char *share_path);
73 
74 static const char *auth_methods_host[] = {"trust", "reject", "md5", "password", "ident", "radius",
75 #ifdef ENABLE_GSS
76  "gss",
77 #endif
78 #ifdef ENABLE_SSPI
79  "sspi",
80 #endif
81 #ifdef USE_PAM
82  "pam", "pam ",
83 #endif
84 #ifdef USE_LDAP
85  "ldap",
86 #endif
87 #ifdef USE_SSL
88  "cert",
89 #endif
90 NULL};
91 static const char *auth_methods_local[] = {"trust", "reject", "md5", "password", "peer", "radius",
92 #ifdef USE_PAM
93  "pam", "pam ",
94 #endif
95 #ifdef USE_LDAP
96  "ldap",
97 #endif
98 NULL};
99 
100 /*
101  * these values are passed in by makefile defines
102  */
103 static char *share_path = NULL;
104 
105 /* values to be obtained from arguments */
106 static char *pg_data = "";
107 static char *encoding = "";
108 static char *locale = "";
109 static char *lc_collate = "";
110 static char *lc_ctype = "";
111 static char *lc_monetary = "";
112 static char *lc_numeric = "";
113 static char *lc_time = "";
114 static char *lc_messages = "";
115 static const char *default_text_search_config = "";
116 static char *username = "";
117 static bool pwprompt = false;
118 static char *pwfilename = NULL;
119 static const char *authmethodhost = "";
120 static const char *authmethodlocal = "";
121 static bool debug = false;
122 static bool noclean = false;
123 static bool do_sync = true;
124 static bool sync_only = false;
125 static bool show_setting = false;
126 static bool data_checksums = false;
127 static char *xlog_dir = "";
128 
129 
130 /* internal vars */
131 static const char *progname;
132 static char *encodingid = "0";
133 static char *bki_file;
134 static char *desc_file;
135 static char *shdesc_file;
136 static char *hba_file;
137 static char *ident_file;
138 static char *conf_file;
139 static char *conversion_file;
140 static char *dictionary_file;
141 static char *info_schema_file;
142 static char *features_file;
143 static char *system_views_file;
144 static bool made_new_pgdata = false;
145 static bool found_existing_pgdata = false;
146 static bool made_new_xlogdir = false;
147 static bool found_existing_xlogdir = false;
148 static char infoversion[100];
149 static bool caught_signal = false;
150 static bool output_failed = false;
151 static int output_errno = 0;
152 static char *pgdata_native;
153 
154 /* defaults */
155 static int n_connections = 10;
156 static int n_buffers = 50;
158 
159 /*
160  * Warning messages for authentication methods
161  */
162 #define AUTHTRUST_WARNING \
163 "# CAUTION: Configuring the system for local \"trust\" authentication\n" \
164 "# allows any local user to connect as any PostgreSQL user, including\n" \
165 "# the database superuser. If you do not trust all your local users,\n" \
166 "# use another authentication method.\n"
167 static char *authwarning = NULL;
168 
169 /*
170  * Centralized knowledge of switches to pass to backend
171  *
172  * Note: we run the backend with -F (fsync disabled) and then do a single
173  * pass of fsync'ing at the end. This is faster than fsync'ing each step.
174  *
175  * Note: in the shell-script version, we also passed PGDATA as a -D switch,
176  * but here it is more convenient to pass it as an environment variable
177  * (no quoting to worry about).
178  */
179 static const char *boot_options = "-F";
180 static const char *backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true";
181 
182 static const char *subdirs[] = {
183  "global",
184  "pg_xlog",
185  "pg_xlog/archive_status",
186  "pg_clog",
187  "pg_commit_ts",
188  "pg_dynshmem",
189  "pg_notify",
190  "pg_serial",
191  "pg_snapshots",
192  "pg_subtrans",
193  "pg_twophase",
194  "pg_multixact/members",
195  "pg_multixact/offsets",
196  "base",
197  "base/1",
198  "pg_replslot",
199  "pg_tblspc",
200  "pg_stat",
201  "pg_stat_tmp",
202  "pg_logical",
203  "pg_logical/snapshots",
204  "pg_logical/mappings"
205 };
206 
207 
208 /* path to 'initdb' binary directory */
209 static char bin_path[MAXPGPATH];
210 static char backend_exec[MAXPGPATH];
211 
212 static char **replace_token(char **lines,
213  const char *token, const char *replacement);
214 
215 #ifndef HAVE_UNIX_SOCKETS
216 static char **filter_lines_with_token(char **lines, const char *token);
217 #endif
218 static char **readfile(const char *path);
219 static void writefile(char *path, char **lines);
220 static void walkdir(char *path, void (*action) (char *fname, bool isdir));
221 static void walktblspc_links(char *path, void (*action) (char *fname, bool isdir));
222 static void pre_sync_fname(char *fname, bool isdir);
223 static void fsync_fname(char *fname, bool isdir);
224 static FILE *popen_check(const char *command, const char *mode);
225 static void exit_nicely(void);
226 static char *get_id(void);
227 static char *get_encoding_id(char *encoding_name);
228 static bool mkdatadir(const char *subdir);
229 static void set_input(char **dest, char *filename);
230 static void check_input(char *path);
231 static void write_version_file(char *extrapath);
232 static void set_null_conf(void);
233 static void test_config_settings(void);
234 static void setup_config(void);
235 static void bootstrap_template1(void);
236 static void setup_auth(void);
237 static void get_set_pwd(void);
238 static void setup_depend(void);
239 static void setup_sysviews(void);
240 static void setup_description(void);
241 static void setup_collation(void);
242 static void setup_conversion(void);
243 static void setup_dictionary(void);
244 static void setup_privileges(void);
245 static void set_info_version(void);
246 static void setup_schema(void);
247 static void load_plpgsql(void);
248 static void vacuum_db(void);
249 static void make_template0(void);
250 static void make_postgres(void);
251 static void perform_fsync(void);
252 static void trapsig(int signum);
253 static void check_ok(void);
254 static char *escape_quotes(const char *src);
255 static int locale_date_order(const char *locale);
256 static void check_locale_name(int category, const char *locale,
257  char **canonname);
258 static bool check_locale_encoding(const char *locale, int encoding);
259 static void setlocales(void);
260 static void usage(const char *progname);
261 void setup_pgdata(void);
262 void setup_bin_paths(const char *argv0);
263 void setup_data_file_paths(void);
264 void setup_locale_encoding(void);
265 void setup_signals(void);
266 void setup_text_search(void);
267 void create_data_directory(void);
268 void create_xlog_symlink(void);
269 void warn_on_mount_point(int error);
270 void initialize_data_directory(void);
271 
272 /*
273  * macros for running pipes to postgres
274  */
275 #define PG_CMD_DECL char cmd[MAXPGPATH]; FILE *cmdfd
276 
277 #define PG_CMD_OPEN \
278 do { \
279  cmdfd = popen_check(cmd, "w"); \
280  if (cmdfd == NULL) \
281  exit_nicely(); /* message already printed by popen_check */ \
282 } while (0)
283 
284 #define PG_CMD_CLOSE \
285 do { \
286  if (pclose_check(cmdfd)) \
287  exit_nicely(); /* message already printed by pclose_check */ \
288 } while (0)
289 
290 #define PG_CMD_PUTS(line) \
291 do { \
292  if (fputs(line, cmdfd) < 0 || fflush(cmdfd) < 0) \
293  output_failed = true, output_errno = errno; \
294 } while (0)
295 
296 #define PG_CMD_PRINTF1(fmt, arg1) \
297 do { \
298  if (fprintf(cmdfd, fmt, arg1) < 0 || fflush(cmdfd) < 0) \
299  output_failed = true, output_errno = errno; \
300 } while (0)
301 
302 #define PG_CMD_PRINTF2(fmt, arg1, arg2) \
303 do { \
304  if (fprintf(cmdfd, fmt, arg1, arg2) < 0 || fflush(cmdfd) < 0) \
305  output_failed = true, output_errno = errno; \
306 } while (0)
307 
308 #define PG_CMD_PRINTF3(fmt, arg1, arg2, arg3) \
309 do { \
310  if (fprintf(cmdfd, fmt, arg1, arg2, arg3) < 0 || fflush(cmdfd) < 0) \
311  output_failed = true, output_errno = errno; \
312 } while (0)
313 
314 #ifndef WIN32
315 #define QUOTE_PATH ""
316 #define DIR_SEP "/"
317 #else
318 #define QUOTE_PATH "\""
319 #define DIR_SEP "\\"
320 #endif
321 
322 static char *
323 escape_quotes(const char *src)
324 {
325  char *result = escape_single_quotes_ascii(src);
326 
327  if (!result)
328  {
329  fprintf(stderr, _("%s: out of memory\n"), progname);
330  exit(1);
331  }
332  return result;
333 }
334 
335 /*
336  * make a copy of the array of lines, with token replaced by replacement
337  * the first time it occurs on each line.
338  *
339  * This does most of what sed was used for in the shell script, but
340  * doesn't need any regexp stuff.
341  */
342 static char **
343 replace_token(char **lines, const char *token, const char *replacement)
344 {
345  int numlines = 1;
346  int i;
347  char **result;
348  int toklen,
349  replen,
350  diff;
351 
352  for (i = 0; lines[i]; i++)
353  numlines++;
354 
355  result = (char **) pg_malloc(numlines * sizeof(char *));
356 
357  toklen = strlen(token);
358  replen = strlen(replacement);
359  diff = replen - toklen;
360 
361  for (i = 0; i < numlines; i++)
362  {
363  char *where;
364  char *newline;
365  int pre;
366 
367  /* just copy pointer if NULL or no change needed */
368  if (lines[i] == NULL || (where = strstr(lines[i], token)) == NULL)
369  {
370  result[i] = lines[i];
371  continue;
372  }
373 
374  /* if we get here a change is needed - set up new line */
375 
376  newline = (char *) pg_malloc(strlen(lines[i]) + diff + 1);
377 
378  pre = where - lines[i];
379 
380  memcpy(newline, lines[i], pre);
381 
382  memcpy(newline + pre, replacement, replen);
383 
384  strcpy(newline + pre + replen, lines[i] + pre + toklen);
385 
386  result[i] = newline;
387  }
388 
389  return result;
390 }
391 
392 /*
393  * make a copy of lines without any that contain the token
394  *
395  * a sort of poor man's grep -v
396  */
397 #ifndef HAVE_UNIX_SOCKETS
398 static char **
399 filter_lines_with_token(char **lines, const char *token)
400 {
401  int numlines = 1;
402  int i,
403  src,
404  dst;
405  char **result;
406 
407  for (i = 0; lines[i]; i++)
408  numlines++;
409 
410  result = (char **) pg_malloc(numlines * sizeof(char *));
411 
412  for (src = 0, dst = 0; src < numlines; src++)
413  {
414  if (lines[src] == NULL || strstr(lines[src], token) == NULL)
415  result[dst++] = lines[src];
416  }
417 
418  return result;
419 }
420 #endif
421 
422 /*
423  * get the lines from a text file
424  */
425 static char **
426 readfile(const char *path)
427 {
428  FILE *infile;
429  int maxlength = 1,
430  linelen = 0;
431  int nlines = 0;
432  int n;
433  char **result;
434  char *buffer;
435  int c;
436 
437  if ((infile = fopen(path, "r")) == NULL)
438  {
439  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
440  progname, path, strerror(errno));
441  exit_nicely();
442  }
443 
444  /* pass over the file twice - the first time to size the result */
445 
446  while ((c = fgetc(infile)) != EOF)
447  {
448  linelen++;
449  if (c == '\n')
450  {
451  nlines++;
452  if (linelen > maxlength)
453  maxlength = linelen;
454  linelen = 0;
455  }
456  }
457 
458  /* handle last line without a terminating newline (yuck) */
459  if (linelen)
460  nlines++;
461  if (linelen > maxlength)
462  maxlength = linelen;
463 
464  /* set up the result and the line buffer */
465  result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
466  buffer = (char *) pg_malloc(maxlength + 1);
467 
468  /* now reprocess the file and store the lines */
469  rewind(infile);
470  n = 0;
471  while (fgets(buffer, maxlength + 1, infile) != NULL && n < nlines)
472  result[n++] = pg_strdup(buffer);
473 
474  fclose(infile);
475  free(buffer);
476  result[n] = NULL;
477 
478  return result;
479 }
480 
481 /*
482  * write an array of lines to a file
483  *
484  * This is only used to write text files. Use fopen "w" not PG_BINARY_W
485  * so that the resulting configuration files are nicely editable on Windows.
486  */
487 static void
488 writefile(char *path, char **lines)
489 {
490  FILE *out_file;
491  char **line;
492 
493  if ((out_file = fopen(path, "w")) == NULL)
494  {
495  fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
496  progname, path, strerror(errno));
497  exit_nicely();
498  }
499  for (line = lines; *line != NULL; line++)
500  {
501  if (fputs(*line, out_file) < 0)
502  {
503  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
504  progname, path, strerror(errno));
505  exit_nicely();
506  }
507  free(*line);
508  }
509  if (fclose(out_file))
510  {
511  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
512  progname, path, strerror(errno));
513  exit_nicely();
514  }
515 }
516 
517 /*
518  * walkdir: recursively walk a directory, applying the action to each
519  * regular file and directory (including the named directory itself).
520  *
521  * Adapted from copydir() in copydir.c.
522  */
523 static void
524 walkdir(char *path, void (*action) (char *fname, bool isdir))
525 {
526  DIR *dir;
527  struct dirent *direntry;
528  char subpath[MAXPGPATH];
529 
530  dir = opendir(path);
531  if (dir == NULL)
532  {
533  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
534  progname, path, strerror(errno));
535  exit_nicely();
536  }
537 
538  while (errno = 0, (direntry = readdir(dir)) != NULL)
539  {
540  struct stat fst;
541 
542  if (strcmp(direntry->d_name, ".") == 0 ||
543  strcmp(direntry->d_name, "..") == 0)
544  continue;
545 
546  snprintf(subpath, MAXPGPATH, "%s/%s", path, direntry->d_name);
547 
548  if (lstat(subpath, &fst) < 0)
549  {
550  fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
551  progname, subpath, strerror(errno));
552  exit_nicely();
553  }
554 
555  if (S_ISDIR(fst.st_mode))
556  walkdir(subpath, action);
557  else if (S_ISREG(fst.st_mode))
558  (*action) (subpath, false);
559  }
560 
561  if (errno)
562  {
563  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
564  progname, path, strerror(errno));
565  exit_nicely();
566  }
567 
568  if (closedir(dir))
569  {
570  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
571  progname, path, strerror(errno));
572  exit_nicely();
573  }
574 
575  /*
576  * It's important to fsync the destination directory itself as individual
577  * file fsyncs don't guarantee that the directory entry for the file is
578  * synced. Recent versions of ext4 have made the window much wider but
579  * it's been an issue for ext3 and other filesystems in the past.
580  */
581  (*action) (path, true);
582 }
583 
584 /*
585  * walktblspc_links: call walkdir on each entry under the given
586  * pg_tblspc directory, or do nothing if pg_tblspc doesn't exist.
587  */
588 static void
589 walktblspc_links(char *path, void (*action) (char *fname, bool isdir))
590 {
591  DIR *dir;
592  struct dirent *direntry;
593  char subpath[MAXPGPATH];
594 
595  dir = opendir(path);
596  if (dir == NULL)
597  {
598  if (errno == ENOENT)
599  return;
600  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
601  progname, path, strerror(errno));
602  exit_nicely();
603  }
604 
605  while (errno = 0, (direntry = readdir(dir)) != NULL)
606  {
607  if (strcmp(direntry->d_name, ".") == 0 ||
608  strcmp(direntry->d_name, "..") == 0)
609  continue;
610 
611  /* fsync the version specific tablespace subdirectory */
612  snprintf(subpath, sizeof(subpath), "%s/%s/%s",
613  path, direntry->d_name, TABLESPACE_VERSION_DIRECTORY);
614 
615  walkdir(subpath, action);
616  }
617 
618  if (errno)
619  {
620  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
621  progname, path, strerror(errno));
622  exit_nicely();
623  }
624 
625  if (closedir(dir))
626  {
627  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
628  progname, path, strerror(errno));
629  exit_nicely();
630  }
631 }
632 
633 /*
634  * Hint to the OS that it should get ready to fsync() this file.
635  */
636 static void
637 pre_sync_fname(char *fname, bool isdir)
638 {
639 #if defined(HAVE_SYNC_FILE_RANGE) || \
640  (defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED))
641  int fd;
642 
643  fd = open(fname, O_RDONLY | PG_BINARY);
644 
645  /*
646  * Some OSs don't allow us to open directories at all (Windows returns
647  * EACCES)
648  */
649  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
650  return;
651 
652  if (fd < 0)
653  {
654  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
655  progname, fname, strerror(errno));
656  exit_nicely();
657  }
658 
659  /*
660  * Prefer sync_file_range, else use posix_fadvise. We ignore any error
661  * here since this operation is only a hint anyway.
662  */
663 #if defined(HAVE_SYNC_FILE_RANGE)
664  sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
665 #elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
666  posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
667 #endif
668 
669  close(fd);
670 #endif
671 }
672 
673 /*
674  * fsync a file or directory
675  *
676  * Try to fsync directories but ignore errors that indicate the OS
677  * just doesn't allow/require fsyncing directories.
678  *
679  * Adapted from fsync_fname() in copydir.c.
680  */
681 static void
682 fsync_fname(char *fname, bool isdir)
683 {
684  int fd;
685  int returncode;
686 
687  /*
688  * Some OSs require directories to be opened read-only whereas other
689  * systems don't allow us to fsync files opened read-only; so we need both
690  * cases here
691  */
692  if (!isdir)
693  fd = open(fname, O_RDWR | PG_BINARY);
694  else
695  fd = open(fname, O_RDONLY | PG_BINARY);
696 
697  /*
698  * Some OSs don't allow us to open directories at all (Windows returns
699  * EACCES)
700  */
701  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
702  return;
703 
704  else if (fd < 0)
705  {
706  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
707  progname, fname, strerror(errno));
708  exit_nicely();
709  }
710 
711  returncode = fsync(fd);
712 
713  /* Some OSs don't allow us to fsync directories at all */
714  if (returncode != 0 && isdir && errno == EBADF)
715  {
716  close(fd);
717  return;
718  }
719 
720  if (returncode != 0)
721  {
722  fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
723  progname, fname, strerror(errno));
724  exit_nicely();
725  }
726 
727  close(fd);
728 }
729 
730 /*
731  * Open a subcommand with suitable error messaging
732  */
733 static FILE *
734 popen_check(const char *command, const char *mode)
735 {
736  FILE *cmdfd;
737 
738  fflush(stdout);
739  fflush(stderr);
740  errno = 0;
741  cmdfd = popen(command, mode);
742  if (cmdfd == NULL)
743  fprintf(stderr, _("%s: could not execute command \"%s\": %s\n"),
744  progname, command, strerror(errno));
745  return cmdfd;
746 }
747 
748 /*
749  * clean up any files we created on failure
750  * if we created the data directory remove it too
751  */
752 static void
754 {
755  if (!noclean)
756  {
757  if (made_new_pgdata)
758  {
759  fprintf(stderr, _("%s: removing data directory \"%s\"\n"),
760  progname, pg_data);
761  if (!rmtree(pg_data, true))
762  fprintf(stderr, _("%s: failed to remove data directory\n"),
763  progname);
764  }
765  else if (found_existing_pgdata)
766  {
767  fprintf(stderr,
768  _("%s: removing contents of data directory \"%s\"\n"),
769  progname, pg_data);
770  if (!rmtree(pg_data, false))
771  fprintf(stderr, _("%s: failed to remove contents of data directory\n"),
772  progname);
773  }
774 
775  if (made_new_xlogdir)
776  {
777  fprintf(stderr, _("%s: removing transaction log directory \"%s\"\n"),
778  progname, xlog_dir);
779  if (!rmtree(xlog_dir, true))
780  fprintf(stderr, _("%s: failed to remove transaction log directory\n"),
781  progname);
782  }
783  else if (found_existing_xlogdir)
784  {
785  fprintf(stderr,
786  _("%s: removing contents of transaction log directory \"%s\"\n"),
787  progname, xlog_dir);
788  if (!rmtree(xlog_dir, false))
789  fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"),
790  progname);
791  }
792  /* otherwise died during startup, do nothing! */
793  }
794  else
795  {
797  fprintf(stderr,
798  _("%s: data directory \"%s\" not removed at user's request\n"),
799  progname, pg_data);
800 
802  fprintf(stderr,
803  _("%s: transaction log directory \"%s\" not removed at user's request\n"),
804  progname, xlog_dir);
805  }
806 
807  exit(1);
808 }
809 
810 /*
811  * find the current user
812  *
813  * on unix make sure it isn't root
814  */
815 static char *
816 get_id(void)
817 {
818  const char *username;
819 
820 #ifndef WIN32
821  if (geteuid() == 0) /* 0 is root's uid */
822  {
823  fprintf(stderr,
824  _("%s: cannot be run as root\n"
825  "Please log in (using, e.g., \"su\") as the "
826  "(unprivileged) user that will\n"
827  "own the server process.\n"),
828  progname);
829  exit(1);
830  }
831 #endif
832 
833  username = get_user_name_or_exit(progname);
834 
835  return pg_strdup(username);
836 }
837 
838 static char *
840 {
841  char result[20];
842 
843  sprintf(result, "%d", enc);
844  return pg_strdup(result);
845 }
846 
847 /*
848  * get the encoding id for a given encoding name
849  */
850 static char *
851 get_encoding_id(char *encoding_name)
852 {
853  int enc;
854 
855  if (encoding_name && *encoding_name)
856  {
857  if ((enc = pg_valid_server_encoding(encoding_name)) >= 0)
858  return encodingid_to_string(enc);
859  }
860  fprintf(stderr, _("%s: \"%s\" is not a valid server encoding name\n"),
861  progname, encoding_name ? encoding_name : "(null)");
862  exit(1);
863 }
864 
865 /*
866  * Support for determining the best default text search configuration.
867  * We key this off the first part of LC_CTYPE (ie, the language name).
868  */
870 {
871  const char *tsconfname;
872  const char *langname;
873 };
874 
876 {
877  {"danish", "da"},
878  {"danish", "Danish"},
879  {"dutch", "nl"},
880  {"dutch", "Dutch"},
881  {"english", "C"},
882  {"english", "POSIX"},
883  {"english", "en"},
884  {"english", "English"},
885  {"finnish", "fi"},
886  {"finnish", "Finnish"},
887  {"french", "fr"},
888  {"french", "French"},
889  {"german", "de"},
890  {"german", "German"},
891  {"hungarian", "hu"},
892  {"hungarian", "Hungarian"},
893  {"italian", "it"},
894  {"italian", "Italian"},
895  {"norwegian", "no"},
896  {"norwegian", "Norwegian"},
897  {"portuguese", "pt"},
898  {"portuguese", "Portuguese"},
899  {"romanian", "ro"},
900  {"russian", "ru"},
901  {"russian", "Russian"},
902  {"spanish", "es"},
903  {"spanish", "Spanish"},
904  {"swedish", "sv"},
905  {"swedish", "Swedish"},
906  {"turkish", "tr"},
907  {"turkish", "Turkish"},
908  {NULL, NULL} /* end marker */
909 };
910 
911 /*
912  * Look for a text search configuration matching lc_ctype, and return its
913  * name; return NULL if no match.
914  */
915 static const char *
916 find_matching_ts_config(const char *lc_type)
917 {
918  int i;
919  char *langname,
920  *ptr;
921 
922  /*
923  * Convert lc_ctype to a language name by stripping everything after an
924  * underscore (usual case) or a hyphen (Windows "locale name"; see
925  * comments at IsoLocaleName()).
926  *
927  * XXX Should ' ' be a stop character? This would select "norwegian" for
928  * the Windows locale "Norwegian (Nynorsk)_Norway.1252". If we do so, we
929  * should also accept the "nn" and "nb" Unix locales.
930  *
931  * Just for paranoia, we also stop at '.' or '@'.
932  */
933  if (lc_type == NULL)
934  langname = pg_strdup("");
935  else
936  {
937  ptr = langname = pg_strdup(lc_type);
938  while (*ptr &&
939  *ptr != '_' && *ptr != '-' && *ptr != '.' && *ptr != '@')
940  ptr++;
941  *ptr = '\0';
942  }
943 
944  for (i = 0; tsearch_config_languages[i].tsconfname; i++)
945  {
946  if (pg_strcasecmp(tsearch_config_languages[i].langname, langname) == 0)
947  {
948  free(langname);
949  return tsearch_config_languages[i].tsconfname;
950  }
951  }
952 
953  free(langname);
954  return NULL;
955 }
956 
957 
958 /*
959  * make the data directory (or one of its subdirectories if subdir is not NULL)
960  */
961 static bool
962 mkdatadir(const char *subdir)
963 {
964  char *path;
965 
966  if (subdir)
967  path = psprintf("%s/%s", pg_data, subdir);
968  else
969  path = pg_strdup(pg_data);
970 
971  if (pg_mkdir_p(path, S_IRWXU) == 0)
972  return true;
973 
974  fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
975  progname, path, strerror(errno));
976 
977  return false;
978 }
979 
980 
981 /*
982  * set name of given input file variable under data directory
983  */
984 static void
985 set_input(char **dest, char *filename)
986 {
987  *dest = psprintf("%s/%s", share_path, filename);
988 }
989 
990 /*
991  * check that given input file exists
992  */
993 static void
994 check_input(char *path)
995 {
996  struct stat statbuf;
997 
998  if (stat(path, &statbuf) != 0)
999  {
1000  if (errno == ENOENT)
1001  {
1002  fprintf(stderr,
1003  _("%s: file \"%s\" does not exist\n"), progname, path);
1004  fprintf(stderr,
1005  _("This might mean you have a corrupted installation or identified\n"
1006  "the wrong directory with the invocation option -L.\n"));
1007  }
1008  else
1009  {
1010  fprintf(stderr,
1011  _("%s: could not access file \"%s\": %s\n"), progname, path,
1012  strerror(errno));
1013  fprintf(stderr,
1014  _("This might mean you have a corrupted installation or identified\n"
1015  "the wrong directory with the invocation option -L.\n"));
1016  }
1017  exit(1);
1018  }
1019  if (!S_ISREG(statbuf.st_mode))
1020  {
1021  fprintf(stderr,
1022  _("%s: file \"%s\" is not a regular file\n"), progname, path);
1023  fprintf(stderr,
1024  _("This might mean you have a corrupted installation or identified\n"
1025  "the wrong directory with the invocation option -L.\n"));
1026  exit(1);
1027  }
1028 }
1029 
1030 /*
1031  * write out the PG_VERSION file in the data dir, or its subdirectory
1032  * if extrapath is not NULL
1033  */
1034 static void
1035 write_version_file(char *extrapath)
1036 {
1037  FILE *version_file;
1038  char *path;
1039 
1040  if (extrapath == NULL)
1041  path = psprintf("%s/PG_VERSION", pg_data);
1042  else
1043  path = psprintf("%s/%s/PG_VERSION", pg_data, extrapath);
1044 
1045  if ((version_file = fopen(path, PG_BINARY_W)) == NULL)
1046  {
1047  fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
1048  progname, path, strerror(errno));
1049  exit_nicely();
1050  }
1051  if (fprintf(version_file, "%s\n", PG_MAJORVERSION) < 0 ||
1052  fclose(version_file))
1053  {
1054  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1055  progname, path, strerror(errno));
1056  exit_nicely();
1057  }
1058  free(path);
1059 }
1060 
1061 /*
1062  * set up an empty config file so we can check config settings by launching
1063  * a test backend
1064  */
1065 static void
1067 {
1068  FILE *conf_file;
1069  char *path;
1070 
1071  path = psprintf("%s/postgresql.conf", pg_data);
1072  conf_file = fopen(path, PG_BINARY_W);
1073  if (conf_file == NULL)
1074  {
1075  fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
1076  progname, path, strerror(errno));
1077  exit_nicely();
1078  }
1079  if (fclose(conf_file))
1080  {
1081  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1082  progname, path, strerror(errno));
1083  exit_nicely();
1084  }
1085  free(path);
1086 }
1087 
1088 /*
1089  * Determine which dynamic shared memory implementation should be used on
1090  * this platform. POSIX shared memory is preferable because the default
1091  * allocation limits are much higher than the limits for System V on most
1092  * systems that support both, but the fact that a platform has shm_open
1093  * doesn't guarantee that that call will succeed when attempted. So, we
1094  * attempt to reproduce what the postmaster will do when allocating a POSIX
1095  * segment in dsm_impl.c; if it doesn't work, we assume it won't work for
1096  * the postmaster either, and configure the cluster for System V shared
1097  * memory instead.
1098  */
1099 static char *
1101 {
1102 #ifdef HAVE_SHM_OPEN
1103  int ntries = 10;
1104 
1105  while (ntries > 0)
1106  {
1107  uint32 handle;
1108  char name[64];
1109  int fd;
1110 
1111  handle = random();
1112  snprintf(name, 64, "/PostgreSQL.%u", handle);
1113  if ((fd = shm_open(name, O_CREAT | O_RDWR | O_EXCL, 0600)) != -1)
1114  {
1115  close(fd);
1116  shm_unlink(name);
1117  return "posix";
1118  }
1119  if (errno != EEXIST)
1120  break;
1121  --ntries;
1122  }
1123 #endif
1124 
1125 #ifdef WIN32
1126  return "windows";
1127 #else
1128  return "sysv";
1129 #endif
1130 }
1131 
1132 /*
1133  * Determine platform-specific config settings
1134  *
1135  * Use reasonable values if kernel will let us, else scale back. Probe
1136  * for max_connections first since it is subject to more constraints than
1137  * shared_buffers.
1138  */
1139 static void
1141 {
1142  /*
1143  * This macro defines the minimum shared_buffers we want for a given
1144  * max_connections value. The arrays show the settings to try.
1145  */
1146 #define MIN_BUFS_FOR_CONNS(nconns) ((nconns) * 10)
1147 
1148  static const int trial_conns[] = {
1149  100, 50, 40, 30, 20, 10
1150  };
1151  static const int trial_bufs[] = {
1152  16384, 8192, 4096, 3584, 3072, 2560, 2048, 1536,
1153  1000, 900, 800, 700, 600, 500,
1154  400, 300, 200, 100, 50
1155  };
1156 
1157  char cmd[MAXPGPATH];
1158  const int connslen = sizeof(trial_conns) / sizeof(int);
1159  const int bufslen = sizeof(trial_bufs) / sizeof(int);
1160  int i,
1161  status,
1162  test_conns,
1163  test_buffs,
1164  ok_buffers = 0;
1165 
1166 
1167  printf(_("selecting default max_connections ... "));
1168  fflush(stdout);
1169 
1170  for (i = 0; i < connslen; i++)
1171  {
1172  test_conns = trial_conns[i];
1173  test_buffs = MIN_BUFS_FOR_CONNS(test_conns);
1174 
1175  snprintf(cmd, sizeof(cmd),
1176  "\"%s\" --boot -x0 %s "
1177  "-c max_connections=%d "
1178  "-c shared_buffers=%d "
1179  "-c dynamic_shared_memory_type=none "
1180  "< \"%s\" > \"%s\" 2>&1",
1182  test_conns, test_buffs,
1183  DEVNULL, DEVNULL);
1184  status = system(cmd);
1185  if (status == 0)
1186  {
1187  ok_buffers = test_buffs;
1188  break;
1189  }
1190  }
1191  if (i >= connslen)
1192  i = connslen - 1;
1193  n_connections = trial_conns[i];
1194 
1195  printf("%d\n", n_connections);
1196 
1197  printf(_("selecting default shared_buffers ... "));
1198  fflush(stdout);
1199 
1200  for (i = 0; i < bufslen; i++)
1201  {
1202  /* Use same amount of memory, independent of BLCKSZ */
1203  test_buffs = (trial_bufs[i] * 8192) / BLCKSZ;
1204  if (test_buffs <= ok_buffers)
1205  {
1206  test_buffs = ok_buffers;
1207  break;
1208  }
1209 
1210  snprintf(cmd, sizeof(cmd),
1211  "\"%s\" --boot -x0 %s "
1212  "-c max_connections=%d "
1213  "-c shared_buffers=%d "
1214  "-c dynamic_shared_memory_type=none "
1215  "< \"%s\" > \"%s\" 2>&1",
1217  n_connections, test_buffs,
1218  DEVNULL, DEVNULL);
1219  status = system(cmd);
1220  if (status == 0)
1221  break;
1222  }
1223  n_buffers = test_buffs;
1224 
1225  if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
1226  printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024);
1227  else
1228  printf("%dkB\n", n_buffers * (BLCKSZ / 1024));
1229 
1230  printf(_("selecting dynamic shared memory implementation ... "));
1231  fflush(stdout);
1233  printf("%s\n", dynamic_shared_memory_type);
1234 }
1235 
1236 /*
1237  * set up all the config files
1238  */
1239 static void
1241 {
1242  char **conflines;
1243  char repltok[MAXPGPATH];
1244  char path[MAXPGPATH];
1245  const char *default_timezone;
1246  char *autoconflines[3];
1247 
1248  fputs(_("creating configuration files ... "), stdout);
1249  fflush(stdout);
1250 
1251  /* postgresql.conf */
1252 
1253  conflines = readfile(conf_file);
1254 
1255  snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections);
1256  conflines = replace_token(conflines, "#max_connections = 100", repltok);
1257 
1258  if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
1259  snprintf(repltok, sizeof(repltok), "shared_buffers = %dMB",
1260  (n_buffers * (BLCKSZ / 1024)) / 1024);
1261  else
1262  snprintf(repltok, sizeof(repltok), "shared_buffers = %dkB",
1263  n_buffers * (BLCKSZ / 1024));
1264  conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);
1265 
1266 #ifdef HAVE_UNIX_SOCKETS
1267  snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
1269 #else
1270  snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
1271 #endif
1272  conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
1273  repltok);
1274 
1275 #if DEF_PGPORT != 5432
1276  snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
1277  conflines = replace_token(conflines, "#port = 5432", repltok);
1278 #endif
1279 
1280  snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
1282  conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);
1283 
1284  snprintf(repltok, sizeof(repltok), "lc_monetary = '%s'",
1286  conflines = replace_token(conflines, "#lc_monetary = 'C'", repltok);
1287 
1288  snprintf(repltok, sizeof(repltok), "lc_numeric = '%s'",
1290  conflines = replace_token(conflines, "#lc_numeric = 'C'", repltok);
1291 
1292  snprintf(repltok, sizeof(repltok), "lc_time = '%s'",
1294  conflines = replace_token(conflines, "#lc_time = 'C'", repltok);
1295 
1296  switch (locale_date_order(lc_time))
1297  {
1298  case DATEORDER_YMD:
1299  strcpy(repltok, "datestyle = 'iso, ymd'");
1300  break;
1301  case DATEORDER_DMY:
1302  strcpy(repltok, "datestyle = 'iso, dmy'");
1303  break;
1304  case DATEORDER_MDY:
1305  default:
1306  strcpy(repltok, "datestyle = 'iso, mdy'");
1307  break;
1308  }
1309  conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok);
1310 
1311  snprintf(repltok, sizeof(repltok),
1312  "default_text_search_config = 'pg_catalog.%s'",
1314  conflines = replace_token(conflines,
1315  "#default_text_search_config = 'pg_catalog.simple'",
1316  repltok);
1317 
1318  default_timezone = select_default_timezone(share_path);
1319  if (default_timezone)
1320  {
1321  snprintf(repltok, sizeof(repltok), "timezone = '%s'",
1322  escape_quotes(default_timezone));
1323  conflines = replace_token(conflines, "#timezone = 'GMT'", repltok);
1324  snprintf(repltok, sizeof(repltok), "log_timezone = '%s'",
1325  escape_quotes(default_timezone));
1326  conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
1327  }
1328 
1329  snprintf(repltok, sizeof(repltok), "dynamic_shared_memory_type = %s",
1331  conflines = replace_token(conflines, "#dynamic_shared_memory_type = posix",
1332  repltok);
1333 
1334 #ifndef USE_PREFETCH
1335  conflines = replace_token(conflines,
1336  "#effective_io_concurrency = 1",
1337  "#effective_io_concurrency = 0");
1338 #endif
1339 
1340  snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
1341 
1342  writefile(path, conflines);
1343  if (chmod(path, S_IRUSR | S_IWUSR) != 0)
1344  {
1345  fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
1346  progname, path, strerror(errno));
1347  exit_nicely();
1348  }
1349 
1350  /*
1351  * create the automatic configuration file to store the configuration
1352  * parameters set by ALTER SYSTEM command. The parameters present in this
1353  * file will override the value of parameters that exists before parse of
1354  * this file.
1355  */
1356  autoconflines[0] = pg_strdup("# Do not edit this file manually!\n");
1357  autoconflines[1] = pg_strdup("# It will be overwritten by the ALTER SYSTEM command.\n");
1358  autoconflines[2] = NULL;
1359 
1360  sprintf(path, "%s/postgresql.auto.conf", pg_data);
1361 
1362  writefile(path, autoconflines);
1363  if (chmod(path, S_IRUSR | S_IWUSR) != 0)
1364  {
1365  fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
1366  progname, path, strerror(errno));
1367  exit_nicely();
1368  }
1369 
1370  free(conflines);
1371 
1372 
1373  /* pg_hba.conf */
1374 
1375  conflines = readfile(hba_file);
1376 
1377 #ifndef HAVE_UNIX_SOCKETS
1378  conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
1379 #else
1380  conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");
1381 #endif
1382 
1383 #ifdef HAVE_IPV6
1384 
1385  /*
1386  * Probe to see if there is really any platform support for IPv6, and
1387  * comment out the relevant pg_hba line if not. This avoids runtime
1388  * warnings if getaddrinfo doesn't actually cope with IPv6. Particularly
1389  * useful on Windows, where executables built on a machine with IPv6 may
1390  * have to run on a machine without.
1391  */
1392  {
1393  struct addrinfo *gai_result;
1394  struct addrinfo hints;
1395  int err = 0;
1396 
1397 #ifdef WIN32
1398  /* need to call WSAStartup before calling getaddrinfo */
1399  WSADATA wsaData;
1400 
1401  err = WSAStartup(MAKEWORD(2, 2), &wsaData);
1402 #endif
1403 
1404  /* for best results, this code should match parse_hba() */
1405  hints.ai_flags = AI_NUMERICHOST;
1406  hints.ai_family = AF_UNSPEC;
1407  hints.ai_socktype = 0;
1408  hints.ai_protocol = 0;
1409  hints.ai_addrlen = 0;
1410  hints.ai_canonname = NULL;
1411  hints.ai_addr = NULL;
1412  hints.ai_next = NULL;
1413 
1414  if (err != 0 ||
1415  getaddrinfo("::1", NULL, &hints, &gai_result) != 0)
1416  conflines = replace_token(conflines,
1417  "host all all ::1",
1418  "#host all all ::1");
1419  }
1420 #else /* !HAVE_IPV6 */
1421  /* If we didn't compile IPV6 support at all, always comment it out */
1422  conflines = replace_token(conflines,
1423  "host all all ::1",
1424  "#host all all ::1");
1425 #endif /* HAVE_IPV6 */
1426 
1427  /* Replace default authentication methods */
1428  conflines = replace_token(conflines,
1429  "@authmethodhost@",
1430  authmethodhost);
1431  conflines = replace_token(conflines,
1432  "@authmethodlocal@",
1433  authmethodlocal);
1434 
1435  conflines = replace_token(conflines,
1436  "@authcomment@",
1437  (strcmp(authmethodlocal, "trust") == 0 || strcmp(authmethodhost, "trust") == 0) ? AUTHTRUST_WARNING : "");
1438 
1439  /* Replace username for replication */
1440  conflines = replace_token(conflines,
1441  "@default_username@",
1442  username);
1443 
1444  snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
1445 
1446  writefile(path, conflines);
1447  if (chmod(path, S_IRUSR | S_IWUSR) != 0)
1448  {
1449  fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
1450  progname, path, strerror(errno));
1451  exit_nicely();
1452  }
1453 
1454  free(conflines);
1455 
1456  /* pg_ident.conf */
1457 
1458  conflines = readfile(ident_file);
1459 
1460  snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data);
1461 
1462  writefile(path, conflines);
1463  if (chmod(path, S_IRUSR | S_IWUSR) != 0)
1464  {
1465  fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
1466  progname, path, strerror(errno));
1467  exit_nicely();
1468  }
1469 
1470  free(conflines);
1471 
1472  check_ok();
1473 }
1474 
1475 
1476 /*
1477  * run the BKI script in bootstrap mode to create template1
1478  */
1479 static void
1481 {
1482  PG_CMD_DECL;
1483  char **line;
1484  char *talkargs = "";
1485  char **bki_lines;
1486  char headerline[MAXPGPATH];
1487  char buf[64];
1488 
1489  printf(_("creating template1 database in %s/base/1 ... "), pg_data);
1490  fflush(stdout);
1491 
1492  if (debug)
1493  talkargs = "-d 5";
1494 
1495  bki_lines = readfile(bki_file);
1496 
1497  /* Check that bki file appears to be of the right version */
1498 
1499  snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n",
1500  PG_MAJORVERSION);
1501 
1502  if (strcmp(headerline, *bki_lines) != 0)
1503  {
1504  fprintf(stderr,
1505  _("%s: input file \"%s\" does not belong to PostgreSQL %s\n"
1506  "Check your installation or specify the correct path "
1507  "using the option -L.\n"),
1508  progname, bki_file, PG_VERSION);
1509  exit_nicely();
1510  }
1511 
1512  /* Substitute for various symbols used in the BKI file */
1513 
1514  sprintf(buf, "%d", NAMEDATALEN);
1515  bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);
1516 
1517  sprintf(buf, "%d", (int) sizeof(Pointer));
1518  bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf);
1519 
1520  bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
1521  (sizeof(Pointer) == 4) ? "i" : "d");
1522 
1523  bki_lines = replace_token(bki_lines, "FLOAT4PASSBYVAL",
1524  FLOAT4PASSBYVAL ? "true" : "false");
1525 
1526  bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
1527  FLOAT8PASSBYVAL ? "true" : "false");
1528 
1529  bki_lines = replace_token(bki_lines, "POSTGRES", escape_quotes(username));
1530 
1531  bki_lines = replace_token(bki_lines, "ENCODING", encodingid);
1532 
1533  bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate));
1534 
1535  bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype));
1536 
1537  /*
1538  * Pass correct LC_xxx environment to bootstrap.
1539  *
1540  * The shell script arranged to restore the LC settings afterwards, but
1541  * there doesn't seem to be any compelling reason to do that.
1542  */
1543  snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate);
1544  putenv(pg_strdup(cmd));
1545 
1546  snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
1547  putenv(pg_strdup(cmd));
1548 
1549  unsetenv("LC_ALL");
1550 
1551  /* Also ensure backend isn't confused by this environment var: */
1552  unsetenv("PGCLIENTENCODING");
1553 
1554  snprintf(cmd, sizeof(cmd),
1555  "\"%s\" --boot -x1 %s %s %s",
1556  backend_exec,
1557  data_checksums ? "-k" : "",
1558  boot_options, talkargs);
1559 
1560  PG_CMD_OPEN;
1561 
1562  for (line = bki_lines; *line != NULL; line++)
1563  {
1564  PG_CMD_PUTS(*line);
1565  free(*line);
1566  }
1567 
1568  PG_CMD_CLOSE;
1569 
1570  free(bki_lines);
1571 
1572  check_ok();
1573 }
1574 
1575 /*
1576  * set up the shadow password table
1577  */
1578 static void
1580 {
1581  PG_CMD_DECL;
1582  const char **line;
1583  static const char *pg_authid_setup[] = {
1584  /*
1585  * The authid table shouldn't be readable except through views, to
1586  * ensure passwords are not publicly visible.
1587  */
1588  "REVOKE ALL on pg_authid FROM public;\n",
1589  NULL
1590  };
1591 
1592  fputs(_("initializing pg_authid ... "), stdout);
1593  fflush(stdout);
1594 
1595  snprintf(cmd, sizeof(cmd),
1596  "\"%s\" %s template1 >%s",
1598  DEVNULL);
1599 
1600  PG_CMD_OPEN;
1601 
1602  for (line = pg_authid_setup; *line != NULL; line++)
1603  PG_CMD_PUTS(*line);
1604 
1605  PG_CMD_CLOSE;
1606 
1607  check_ok();
1608 }
1609 
1610 /*
1611  * get the superuser password if required, and call postgres to set it
1612  */
1613 static void
1615 {
1616  PG_CMD_DECL;
1617 
1618  char *pwd1,
1619  *pwd2;
1620 
1621  if (pwprompt)
1622  {
1623  /*
1624  * Read password from terminal
1625  */
1626  pwd1 = simple_prompt("Enter new superuser password: ", 100, false);
1627  pwd2 = simple_prompt("Enter it again: ", 100, false);
1628  if (strcmp(pwd1, pwd2) != 0)
1629  {
1630  fprintf(stderr, _("Passwords didn't match.\n"));
1631  exit_nicely();
1632  }
1633  free(pwd2);
1634  }
1635  else
1636  {
1637  /*
1638  * Read password from file
1639  *
1640  * Ideally this should insist that the file not be world-readable.
1641  * However, this option is mainly intended for use on Windows where
1642  * file permissions may not exist at all, so we'll skip the paranoia
1643  * for now.
1644  */
1645  FILE *pwf = fopen(pwfilename, "r");
1646  char pwdbuf[MAXPGPATH];
1647  int i;
1648 
1649  if (!pwf)
1650  {
1651  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
1652  progname, pwfilename, strerror(errno));
1653  exit_nicely();
1654  }
1655  if (!fgets(pwdbuf, sizeof(pwdbuf), pwf))
1656  {
1657  if (ferror(pwf))
1658  fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"),
1659  progname, pwfilename, strerror(errno));
1660  else
1661  fprintf(stderr, _("%s: password file \"%s\" is empty\n"),
1662  progname, pwfilename);
1663  exit_nicely();
1664  }
1665  fclose(pwf);
1666 
1667  i = strlen(pwdbuf);
1668  while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n'))
1669  pwdbuf[--i] = '\0';
1670 
1671  pwd1 = pg_strdup(pwdbuf);
1672 
1673  }
1674  printf(_("setting password ... "));
1675  fflush(stdout);
1676 
1677  snprintf(cmd, sizeof(cmd),
1678  "\"%s\" %s template1 >%s",
1680  DEVNULL);
1681 
1682  PG_CMD_OPEN;
1683 
1684  PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n",
1685  username, escape_quotes(pwd1));
1686 
1687  /* MM: pwd1 is no longer needed, freeing it */
1688  free(pwd1);
1689 
1690  PG_CMD_CLOSE;
1691 
1692  check_ok();
1693 }
1694 
1695 /*
1696  * set up pg_depend
1697  */
1698 static void
1700 {
1701  PG_CMD_DECL;
1702  const char **line;
1703  static const char *pg_depend_setup[] = {
1704  /*
1705  * Make PIN entries in pg_depend for all objects made so far in the
1706  * tables that the dependency code handles. This is overkill (the
1707  * system doesn't really depend on having every last weird datatype,
1708  * for instance) but generating only the minimum required set of
1709  * dependencies seems hard.
1710  *
1711  * Note that we deliberately do not pin the system views, which
1712  * haven't been created yet. Also, no conversions, databases, or
1713  * tablespaces are pinned.
1714  *
1715  * First delete any already-made entries; PINs override all else, and
1716  * must be the only entries for their objects.
1717  */
1718  "DELETE FROM pg_depend;\n",
1719  "VACUUM pg_depend;\n",
1720  "DELETE FROM pg_shdepend;\n",
1721  "VACUUM pg_shdepend;\n",
1722 
1723  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1724  " FROM pg_class;\n",
1725  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1726  " FROM pg_proc;\n",
1727  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1728  " FROM pg_type;\n",
1729  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1730  " FROM pg_cast;\n",
1731  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1732  " FROM pg_constraint;\n",
1733  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1734  " FROM pg_attrdef;\n",
1735  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1736  " FROM pg_language;\n",
1737  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1738  " FROM pg_operator;\n",
1739  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1740  " FROM pg_opclass;\n",
1741  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1742  " FROM pg_opfamily;\n",
1743  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1744  " FROM pg_amop;\n",
1745  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1746  " FROM pg_amproc;\n",
1747  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1748  " FROM pg_rewrite;\n",
1749  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1750  " FROM pg_trigger;\n",
1751 
1752  /*
1753  * restriction here to avoid pinning the public namespace
1754  */
1755  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1756  " FROM pg_namespace "
1757  " WHERE nspname LIKE 'pg%';\n",
1758 
1759  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1760  " FROM pg_ts_parser;\n",
1761  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1762  " FROM pg_ts_dict;\n",
1763  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1764  " FROM pg_ts_template;\n",
1765  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1766  " FROM pg_ts_config;\n",
1767  "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1768  " FROM pg_collation;\n",
1769  "INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
1770  " FROM pg_authid;\n",
1771  NULL
1772  };
1773 
1774  fputs(_("initializing dependencies ... "), stdout);
1775  fflush(stdout);
1776 
1777  snprintf(cmd, sizeof(cmd),
1778  "\"%s\" %s template1 >%s",
1780  DEVNULL);
1781 
1782  PG_CMD_OPEN;
1783 
1784  for (line = pg_depend_setup; *line != NULL; line++)
1785  PG_CMD_PUTS(*line);
1786 
1787  PG_CMD_CLOSE;
1788 
1789  check_ok();
1790 }
1791 
1792 /*
1793  * set up system views
1794  */
1795 static void
1797 {
1798  PG_CMD_DECL;
1799  char **line;
1800  char **sysviews_setup;
1801 
1802  fputs(_("creating system views ... "), stdout);
1803  fflush(stdout);
1804 
1805  sysviews_setup = readfile(system_views_file);
1806 
1807  /*
1808  * We use -j here to avoid backslashing stuff in system_views.sql
1809  */
1810  snprintf(cmd, sizeof(cmd),
1811  "\"%s\" %s -j template1 >%s",
1813  DEVNULL);
1814 
1815  PG_CMD_OPEN;
1816 
1817  for (line = sysviews_setup; *line != NULL; line++)
1818  {
1819  PG_CMD_PUTS(*line);
1820  free(*line);
1821  }
1822 
1823  PG_CMD_CLOSE;
1824 
1825  free(sysviews_setup);
1826 
1827  check_ok();
1828 }
1829 
1830 /*
1831  * load description data
1832  */
1833 static void
1835 {
1836  PG_CMD_DECL;
1837 
1838  fputs(_("loading system objects' descriptions ... "), stdout);
1839  fflush(stdout);
1840 
1841  snprintf(cmd, sizeof(cmd),
1842  "\"%s\" %s template1 >%s",
1844  DEVNULL);
1845 
1846  PG_CMD_OPEN;
1847 
1848  PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_description ( "
1849  " objoid oid, "
1850  " classname name, "
1851  " objsubid int4, "
1852  " description text) WITHOUT OIDS;\n");
1853 
1854  PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n",
1856 
1857  PG_CMD_PUTS("INSERT INTO pg_description "
1858  " SELECT t.objoid, c.oid, t.objsubid, t.description "
1859  " FROM tmp_pg_description t, pg_class c "
1860  " WHERE c.relname = t.classname;\n");
1861 
1862  PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( "
1863  " objoid oid, "
1864  " classname name, "
1865  " description text) WITHOUT OIDS;\n");
1866 
1867  PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n",
1869 
1870  PG_CMD_PUTS("INSERT INTO pg_shdescription "
1871  " SELECT t.objoid, c.oid, t.description "
1872  " FROM tmp_pg_shdescription t, pg_class c "
1873  " WHERE c.relname = t.classname;\n");
1874 
1875  /* Create default descriptions for operator implementation functions */
1876  PG_CMD_PUTS("WITH funcdescs AS ( "
1877  "SELECT p.oid as p_oid, oprname, "
1878  "coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc "
1879  "FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid ) "
1880  "INSERT INTO pg_description "
1881  " SELECT p_oid, 'pg_proc'::regclass, 0, "
1882  " 'implementation of ' || oprname || ' operator' "
1883  " FROM funcdescs "
1884  " WHERE opdesc NOT LIKE 'deprecated%' AND "
1885  " NOT EXISTS (SELECT 1 FROM pg_description "
1886  " WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass);\n");
1887 
1888  PG_CMD_CLOSE;
1889 
1890  check_ok();
1891 }
1892 
1893 #ifdef HAVE_LOCALE_T
1894 /*
1895  * "Normalize" a locale name, stripping off encoding tags such as
1896  * ".utf8" (e.g., "en_US.utf8" -> "en_US", but "br_FR.iso885915@euro"
1897  * -> "br_FR@euro"). Return true if a new, different name was
1898  * generated.
1899  */
1900 static bool
1901 normalize_locale_name(char *new, const char *old)
1902 {
1903  char *n = new;
1904  const char *o = old;
1905  bool changed = false;
1906 
1907  while (*o)
1908  {
1909  if (*o == '.')
1910  {
1911  /* skip over encoding tag such as ".utf8" or ".UTF-8" */
1912  o++;
1913  while ((*o >= 'A' && *o <= 'Z')
1914  || (*o >= 'a' && *o <= 'z')
1915  || (*o >= '0' && *o <= '9')
1916  || (*o == '-'))
1917  o++;
1918  changed = true;
1919  }
1920  else
1921  *n++ = *o++;
1922  }
1923  *n = '\0';
1924 
1925  return changed;
1926 }
1927 #endif /* HAVE_LOCALE_T */
1928 
1929 /*
1930  * populate pg_collation
1931  */
1932 static void
1934 {
1935 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
1936  int i;
1937  FILE *locale_a_handle;
1938  char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
1939  int count = 0;
1940 
1941  PG_CMD_DECL;
1942 #endif
1943 
1944  fputs(_("creating collations ... "), stdout);
1945  fflush(stdout);
1946 
1947 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
1948  snprintf(cmd, sizeof(cmd),
1949  "\"%s\" %s template1 >%s",
1951  DEVNULL);
1952 
1953  locale_a_handle = popen_check("locale -a", "r");
1954  if (!locale_a_handle)
1955  return; /* complaint already printed */
1956 
1957  PG_CMD_OPEN;
1958 
1959  PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_collation ( "
1960  " collname name, "
1961  " locale name, "
1962  " encoding int) WITHOUT OIDS;\n");
1963 
1964  while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
1965  {
1966  size_t len;
1967  int enc;
1968  bool skip;
1969  char *quoted_locale;
1970  char alias[NAMEDATALEN];
1971 
1972  len = strlen(localebuf);
1973 
1974  if (len == 0 || localebuf[len - 1] != '\n')
1975  {
1976  if (debug)
1977  fprintf(stderr, _("%s: locale name too long, skipped: \"%s\"\n"),
1978  progname, localebuf);
1979  continue;
1980  }
1981  localebuf[len - 1] = '\0';
1982 
1983  /*
1984  * Some systems have locale names that don't consist entirely of ASCII
1985  * letters (such as "bokm&aring;l" or "fran&ccedil;ais"). This is
1986  * pretty silly, since we need the locale itself to interpret the
1987  * non-ASCII characters. We can't do much with those, so we filter
1988  * them out.
1989  */
1990  skip = false;
1991  for (i = 0; i < len; i++)
1992  {
1993  if (IS_HIGHBIT_SET(localebuf[i]))
1994  {
1995  skip = true;
1996  break;
1997  }
1998  }
1999  if (skip)
2000  {
2001  if (debug)
2002  fprintf(stderr, _("%s: locale name has non-ASCII characters, skipped: \"%s\"\n"),
2003  progname, localebuf);
2004  continue;
2005  }
2006 
2007  enc = pg_get_encoding_from_locale(localebuf, debug);
2008  if (enc < 0)
2009  {
2010  /* error message printed by pg_get_encoding_from_locale() */
2011  continue;
2012  }
2013  if (!PG_VALID_BE_ENCODING(enc))
2014  continue; /* ignore locales for client-only encodings */
2015  if (enc == PG_SQL_ASCII)
2016  continue; /* C/POSIX are already in the catalog */
2017 
2018  count++;
2019 
2020  quoted_locale = escape_quotes(localebuf);
2021 
2022  PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
2023  quoted_locale, quoted_locale, enc);
2024 
2025  /*
2026  * Generate aliases such as "en_US" in addition to "en_US.utf8" for
2027  * ease of use. Note that collation names are unique per encoding
2028  * only, so this doesn't clash with "en_US" for LATIN1, say.
2029  */
2030  if (normalize_locale_name(alias, localebuf))
2031  {
2032  char *quoted_alias = escape_quotes(alias);
2033 
2034  PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
2035  quoted_alias, quoted_locale, enc);
2036  free(quoted_alias);
2037  }
2038  free(quoted_locale);
2039  }
2040 
2041  /* Add an SQL-standard name */
2042  PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n", PG_UTF8);
2043 
2044  /*
2045  * When copying collations to the final location, eliminate aliases that
2046  * conflict with an existing locale name for the same encoding. For
2047  * example, "br_FR.iso88591" is normalized to "br_FR", both for encoding
2048  * LATIN1. But the unnormalized locale "br_FR" already exists for LATIN1.
2049  * Prefer the alias that matches the OS locale name, else the first locale
2050  * name by sort order (arbitrary choice to be deterministic).
2051  *
2052  * Also, eliminate any aliases that conflict with pg_collation's
2053  * hard-wired entries for "C" etc.
2054  */
2055  PG_CMD_PUTS("INSERT INTO pg_collation (collname, collnamespace, collowner, collencoding, collcollate, collctype) "
2056  " SELECT DISTINCT ON (collname, encoding)"
2057  " collname, "
2058  " (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') AS collnamespace, "
2059  " (SELECT relowner FROM pg_class WHERE relname = 'pg_collation') AS collowner, "
2060  " encoding, locale, locale "
2061  " FROM tmp_pg_collation"
2062  " WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)"
2063  " ORDER BY collname, encoding, (collname = locale) DESC, locale;\n");
2064 
2065  pclose(locale_a_handle);
2066  PG_CMD_CLOSE;
2067 
2068  check_ok();
2069  if (count == 0 && !debug)
2070  {
2071  printf(_("No usable system locales were found.\n"));
2072  printf(_("Use the option \"--debug\" to see details.\n"));
2073  }
2074 #else /* not HAVE_LOCALE_T && not WIN32 */
2075  printf(_("not supported on this platform\n"));
2076  fflush(stdout);
2077 #endif /* not HAVE_LOCALE_T && not WIN32 */
2078 }
2079 
2080 /*
2081  * load conversion functions
2082  */
2083 static void
2085 {
2086  PG_CMD_DECL;
2087  char **line;
2088  char **conv_lines;
2089 
2090  fputs(_("creating conversions ... "), stdout);
2091  fflush(stdout);
2092 
2093  snprintf(cmd, sizeof(cmd),
2094  "\"%s\" %s template1 >%s",
2096  DEVNULL);
2097 
2098  PG_CMD_OPEN;
2099 
2100  conv_lines = readfile(conversion_file);
2101  for (line = conv_lines; *line != NULL; line++)
2102  {
2103  if (strstr(*line, "DROP CONVERSION") != *line)
2104  PG_CMD_PUTS(*line);
2105  free(*line);
2106  }
2107 
2108  free(conv_lines);
2109 
2110  PG_CMD_CLOSE;
2111 
2112  check_ok();
2113 }
2114 
2115 /*
2116  * load extra dictionaries (Snowball stemmers)
2117  */
2118 static void
2120 {
2121  PG_CMD_DECL;
2122  char **line;
2123  char **conv_lines;
2124 
2125  fputs(_("creating dictionaries ... "), stdout);
2126  fflush(stdout);
2127 
2128  /*
2129  * We use -j here to avoid backslashing stuff
2130  */
2131  snprintf(cmd, sizeof(cmd),
2132  "\"%s\" %s -j template1 >%s",
2134  DEVNULL);
2135 
2136  PG_CMD_OPEN;
2137 
2138  conv_lines = readfile(dictionary_file);
2139  for (line = conv_lines; *line != NULL; line++)
2140  {
2141  PG_CMD_PUTS(*line);
2142  free(*line);
2143  }
2144 
2145  free(conv_lines);
2146 
2147  PG_CMD_CLOSE;
2148 
2149  check_ok();
2150 }
2151 
2152 /*
2153  * Set up privileges
2154  *
2155  * We mark most system catalogs as world-readable. We don't currently have
2156  * to touch functions, languages, or databases, because their default
2157  * permissions are OK.
2158  *
2159  * Some objects may require different permissions by default, so we
2160  * make sure we don't overwrite privilege sets that have already been
2161  * set (NOT NULL).
2162  */
2163 static void
2165 {
2166  PG_CMD_DECL;
2167  char **line;
2168  char **priv_lines;
2169  static char *privileges_setup[] = {
2170  "UPDATE pg_class "
2171  " SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' "
2172  " WHERE relkind IN ('r', 'v', 'm', 'S') AND relacl IS NULL;\n",
2173  "GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n",
2174  "GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n",
2175  "REVOKE ALL ON pg_largeobject FROM PUBLIC;\n",
2176  NULL
2177  };
2178 
2179  fputs(_("setting privileges on built-in objects ... "), stdout);
2180  fflush(stdout);
2181 
2182  snprintf(cmd, sizeof(cmd),
2183  "\"%s\" %s template1 >%s",
2185  DEVNULL);
2186 
2187  PG_CMD_OPEN;
2188 
2189  priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
2191  for (line = priv_lines; *line != NULL; line++)
2192  PG_CMD_PUTS(*line);
2193 
2194  PG_CMD_CLOSE;
2195 
2196  check_ok();
2197 }
2198 
2199 /*
2200  * extract the strange version of version required for information schema
2201  * (09.08.0007abc)
2202  */
2203 static void
2205 {
2206  char *letterversion;
2207  long major = 0,
2208  minor = 0,
2209  micro = 0;
2210  char *endptr;
2211  char *vstr = pg_strdup(PG_VERSION);
2212  char *ptr;
2213 
2214  ptr = vstr + (strlen(vstr) - 1);
2215  while (ptr != vstr && (*ptr < '0' || *ptr > '9'))
2216  ptr--;
2217  letterversion = ptr + 1;
2218  major = strtol(vstr, &endptr, 10);
2219  if (*endptr)
2220  minor = strtol(endptr + 1, &endptr, 10);
2221  if (*endptr)
2222  micro = strtol(endptr + 1, &endptr, 10);
2223  snprintf(infoversion, sizeof(infoversion), "%02ld.%02ld.%04ld%s",
2224  major, minor, micro, letterversion);
2225 }
2226 
2227 /*
2228  * load info schema and populate from features file
2229  */
2230 static void
2232 {
2233  PG_CMD_DECL;
2234  char **line;
2235  char **lines;
2236 
2237  fputs(_("creating information schema ... "), stdout);
2238  fflush(stdout);
2239 
2240  lines = readfile(info_schema_file);
2241 
2242  /*
2243  * We use -j here to avoid backslashing stuff in information_schema.sql
2244  */
2245  snprintf(cmd, sizeof(cmd),
2246  "\"%s\" %s -j template1 >%s",
2248  DEVNULL);
2249 
2250  PG_CMD_OPEN;
2251 
2252  for (line = lines; *line != NULL; line++)
2253  {
2254  PG_CMD_PUTS(*line);
2255  free(*line);
2256  }
2257 
2258  free(lines);
2259 
2260  PG_CMD_CLOSE;
2261 
2262  snprintf(cmd, sizeof(cmd),
2263  "\"%s\" %s template1 >%s",
2265  DEVNULL);
2266 
2267  PG_CMD_OPEN;
2268 
2269  PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info "
2270  " SET character_value = '%s' "
2271  " WHERE implementation_info_name = 'DBMS VERSION';\n",
2272  infoversion);
2273 
2274  PG_CMD_PRINTF1("COPY information_schema.sql_features "
2275  " (feature_id, feature_name, sub_feature_id, "
2276  " sub_feature_name, is_supported, comments) "
2277  " FROM E'%s';\n",
2279 
2280  PG_CMD_CLOSE;
2281 
2282  check_ok();
2283 }
2284 
2285 /*
2286  * load PL/pgsql server-side language
2287  */
2288 static void
2290 {
2291  PG_CMD_DECL;
2292 
2293  fputs(_("loading PL/pgSQL server-side language ... "), stdout);
2294  fflush(stdout);
2295 
2296  snprintf(cmd, sizeof(cmd),
2297  "\"%s\" %s template1 >%s",
2299  DEVNULL);
2300 
2301  PG_CMD_OPEN;
2302 
2303  PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n");
2304 
2305  PG_CMD_CLOSE;
2306 
2307  check_ok();
2308 }
2309 
2310 /*
2311  * clean everything up in template1
2312  */
2313 static void
2315 {
2316  PG_CMD_DECL;
2317 
2318  fputs(_("vacuuming database template1 ... "), stdout);
2319  fflush(stdout);
2320 
2321  snprintf(cmd, sizeof(cmd),
2322  "\"%s\" %s template1 >%s",
2324  DEVNULL);
2325 
2326  PG_CMD_OPEN;
2327 
2328  /* Run analyze before VACUUM so the statistics are frozen. */
2329  PG_CMD_PUTS("ANALYZE;\nVACUUM FREEZE;\n");
2330 
2331  PG_CMD_CLOSE;
2332 
2333  check_ok();
2334 }
2335 
2336 /*
2337  * copy template1 to template0
2338  */
2339 static void
2341 {
2342  PG_CMD_DECL;
2343  const char **line;
2344  static const char *template0_setup[] = {
2345  "CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n",
2346 
2347  /*
2348  * We use the OID of template0 to determine lastsysoid
2349  */
2350  "UPDATE pg_database SET datlastsysoid = "
2351  " (SELECT oid FROM pg_database "
2352  " WHERE datname = 'template0');\n",
2353 
2354  /*
2355  * Explicitly revoke public create-schema and create-temp-table
2356  * privileges in template1 and template0; else the latter would be on
2357  * by default
2358  */
2359  "REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n",
2360  "REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n",
2361 
2362  "COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n",
2363 
2364  /*
2365  * Finally vacuum to clean up dead rows in pg_database
2366  */
2367  "VACUUM FULL pg_database;\n",
2368  NULL
2369  };
2370 
2371  fputs(_("copying template1 to template0 ... "), stdout);
2372  fflush(stdout);
2373 
2374  snprintf(cmd, sizeof(cmd),
2375  "\"%s\" %s template1 >%s",
2377  DEVNULL);
2378 
2379  PG_CMD_OPEN;
2380 
2381  for (line = template0_setup; *line; line++)
2382  PG_CMD_PUTS(*line);
2383 
2384  PG_CMD_CLOSE;
2385 
2386  check_ok();
2387 }
2388 
2389 /*
2390  * copy template1 to postgres
2391  */
2392 static void
2394 {
2395  PG_CMD_DECL;
2396  const char **line;
2397  static const char *postgres_setup[] = {
2398  "CREATE DATABASE postgres;\n",
2399  "COMMENT ON DATABASE postgres IS 'default administrative connection database';\n",
2400  NULL
2401  };
2402 
2403  fputs(_("copying template1 to postgres ... "), stdout);
2404  fflush(stdout);
2405 
2406  snprintf(cmd, sizeof(cmd),
2407  "\"%s\" %s template1 >%s",
2409  DEVNULL);
2410 
2411  PG_CMD_OPEN;
2412 
2413  for (line = postgres_setup; *line; line++)
2414  PG_CMD_PUTS(*line);
2415 
2416  PG_CMD_CLOSE;
2417 
2418  check_ok();
2419 }
2420 
2421 /*
2422  * fsync everything down to disk
2423  */
2424 static void
2426 {
2427  char pdir[MAXPGPATH];
2428  char pg_tblspc[MAXPGPATH];
2429 
2430  fputs(_("syncing data to disk ... "), stdout);
2431  fflush(stdout);
2432 
2433  /*
2434  * We need to name the parent of PGDATA. get_parent_directory() isn't
2435  * enough here, because it can result in an empty string.
2436  */
2437  snprintf(pdir, MAXPGPATH, "%s/..", pg_data);
2438  canonicalize_path(pdir);
2439 
2440  /*
2441  * Hint to the OS so that we're going to fsync each of these files soon.
2442  */
2443 
2444  /* first the parent of the PGDATA directory */
2445  pre_sync_fname(pdir, true);
2446 
2447  /* then recursively through the data directory */
2449 
2450  /* now do the same thing for everything under pg_tblspc */
2451  snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pg_data);
2452  walktblspc_links(pg_tblspc, pre_sync_fname);
2453 
2454  /*
2455  * Now, do the fsync()s in the same order.
2456  */
2457 
2458  /* first the parent of the PGDATA directory */
2459  fsync_fname(pdir, true);
2460 
2461  /* then recursively through the data directory */
2463 
2464  /* and now the same for all tablespaces */
2465  walktblspc_links(pg_tblspc, fsync_fname);
2466 
2467  check_ok();
2468 }
2469 
2470 
2471 /*
2472  * signal handler in case we are interrupted.
2473  *
2474  * The Windows runtime docs at
2475  * http://msdn.microsoft.com/library/en-us/vclib/html/_crt_signal.asp
2476  * specifically forbid a number of things being done from a signal handler,
2477  * including IO, memory allocation and system calls, and only allow jmpbuf
2478  * if you are handling SIGFPE.
2479  *
2480  * I avoided doing the forbidden things by setting a flag instead of calling
2481  * exit_nicely() directly.
2482  *
2483  * Also note the behaviour of Windows with SIGINT, which says this:
2484  * Note SIGINT is not supported for any Win32 application, including
2485  * Windows 98/Me and Windows NT/2000/XP. When a CTRL+C interrupt occurs,
2486  * Win32 operating systems generate a new thread to specifically handle
2487  * that interrupt. This can cause a single-thread application such as UNIX,
2488  * to become multithreaded, resulting in unexpected behavior.
2489  *
2490  * I have no idea how to handle this. (Strange they call UNIX an application!)
2491  * So this will need some testing on Windows.
2492  */
2493 static void
2494 trapsig(int signum)
2495 {
2496  /* handle systems that reset the handler, like Windows (grr) */
2497  pqsignal(signum, trapsig);
2498  caught_signal = true;
2499 }
2500 
2501 /*
2502  * call exit_nicely() if we got a signal, or else output "ok".
2503  */
2504 static void
2506 {
2507  if (caught_signal)
2508  {
2509  printf(_("caught signal\n"));
2510  fflush(stdout);
2511  exit_nicely();
2512  }
2513  else if (output_failed)
2514  {
2515  printf(_("could not write to child process: %s\n"),
2517  fflush(stdout);
2518  exit_nicely();
2519  }
2520  else
2521  {
2522  /* all seems well */
2523  printf(_("ok\n"));
2524  fflush(stdout);
2525  }
2526 }
2527 
2528 /* Hack to suppress a warning about %x from some versions of gcc */
2529 static inline size_t
2530 my_strftime(char *s, size_t max, const char *fmt, const struct tm * tm)
2531 {
2532  return strftime(s, max, fmt, tm);
2533 }
2534 
2535 /*
2536  * Determine likely date order from locale
2537  */
2538 static int
2540 {
2541  struct tm testtime;
2542  char buf[128];
2543  char *posD;
2544  char *posM;
2545  char *posY;
2546  char *save;
2547  size_t res;
2548  int result;
2549 
2550  result = DATEORDER_MDY; /* default */
2551 
2552  save = setlocale(LC_TIME, NULL);
2553  if (!save)
2554  return result;
2555  save = pg_strdup(save);
2556 
2557  setlocale(LC_TIME, locale);
2558 
2559  memset(&testtime, 0, sizeof(testtime));
2560  testtime.tm_mday = 22;
2561  testtime.tm_mon = 10; /* November, should come out as "11" */
2562  testtime.tm_year = 133; /* 2033 */
2563 
2564  res = my_strftime(buf, sizeof(buf), "%x", &testtime);
2565 
2566  setlocale(LC_TIME, save);
2567  free(save);
2568 
2569  if (res == 0)
2570  return result;
2571 
2572  posM = strstr(buf, "11");
2573  posD = strstr(buf, "22");
2574  posY = strstr(buf, "33");
2575 
2576  if (!posM || !posD || !posY)
2577  return result;
2578 
2579  if (posY < posM && posM < posD)
2580  result = DATEORDER_YMD;
2581  else if (posD < posM)
2582  result = DATEORDER_DMY;
2583  else
2584  result = DATEORDER_MDY;
2585 
2586  return result;
2587 }
2588 
2589 /*
2590  * Verify that locale name is valid for the locale category.
2591  *
2592  * If successful, and canonname isn't NULL, a malloc'd copy of the locale's
2593  * canonical name is stored there. This is especially useful for figuring out
2594  * what locale name "" means (ie, the environment value). (Actually,
2595  * it seems that on most implementations that's the only thing it's good for;
2596  * we could wish that setlocale gave back a canonically spelled version of
2597  * the locale name, but typically it doesn't.)
2598  *
2599  * this should match the backend's check_locale() function
2600  */
2601 static void
2602 check_locale_name(int category, const char *locale, char **canonname)
2603 {
2604  char *save;
2605  char *res;
2606 
2607  if (canonname)
2608  *canonname = NULL; /* in case of failure */
2609 
2610  save = setlocale(category, NULL);
2611  if (!save)
2612  {
2613  fprintf(stderr, _("%s: setlocale() failed\n"),
2614  progname);
2615  exit(1);
2616  }
2617 
2618  /* save may be pointing at a modifiable scratch variable, so copy it. */
2619  save = pg_strdup(save);
2620 
2621  /* set the locale with setlocale, to see if it accepts it. */
2622  res = setlocale(category, locale);
2623 
2624  /* save canonical name if requested. */
2625  if (res && canonname)
2626  *canonname = pg_strdup(res);
2627 
2628  /* restore old value. */
2629  if (!setlocale(category, save))
2630  {
2631  fprintf(stderr, _("%s: failed to restore old locale \"%s\"\n"),
2632  progname, save);
2633  exit(1);
2634  }
2635  free(save);
2636 
2637  /* complain if locale wasn't valid */
2638  if (res == NULL)
2639  {
2640  if (*locale)
2641  fprintf(stderr, _("%s: invalid locale name \"%s\"\n"),
2642  progname, locale);
2643  else
2644  {
2645  /*
2646  * If no relevant switch was given on command line, locale is an
2647  * empty string, which is not too helpful to report. Presumably
2648  * setlocale() found something it did not like in the environment.
2649  * Ideally we'd report the bad environment variable, but since
2650  * setlocale's behavior is implementation-specific, it's hard to
2651  * be sure what it didn't like. Print a safe generic message.
2652  */
2653  fprintf(stderr, _("%s: invalid locale settings; check LANG and LC_* environment variables\n"),
2654  progname);
2655  }
2656  exit(1);
2657  }
2658 }
2659 
2660 /*
2661  * check if the chosen encoding matches the encoding required by the locale
2662  *
2663  * this should match the similar check in the backend createdb() function
2664  */
2665 static bool
2666 check_locale_encoding(const char *locale, int user_enc)
2667 {
2668  int locale_enc;
2669 
2670  locale_enc = pg_get_encoding_from_locale(locale, true);
2671 
2672  /* See notes in createdb() to understand these tests */
2673  if (!(locale_enc == user_enc ||
2674  locale_enc == PG_SQL_ASCII ||
2675  locale_enc == -1 ||
2676 #ifdef WIN32
2677  user_enc == PG_UTF8 ||
2678 #endif
2679  user_enc == PG_SQL_ASCII))
2680  {
2681  fprintf(stderr, _("%s: encoding mismatch\n"), progname);
2682  fprintf(stderr,
2683  _("The encoding you selected (%s) and the encoding that the\n"
2684  "selected locale uses (%s) do not match. This would lead to\n"
2685  "misbehavior in various character string processing functions.\n"
2686  "Rerun %s and either do not specify an encoding explicitly,\n"
2687  "or choose a matching combination.\n"),
2688  pg_encoding_to_char(user_enc),
2689  pg_encoding_to_char(locale_enc),
2690  progname);
2691  return false;
2692  }
2693  return true;
2694 }
2695 
2696 /*
2697  * set up the locale variables
2698  *
2699  * assumes we have called setlocale(LC_ALL, "") -- see set_pglocale_pgservice
2700  */
2701 static void
2703 {
2704  char *canonname;
2705 
2706  /* set empty lc_* values to locale config if set */
2707 
2708  if (strlen(locale) > 0)
2709  {
2710  if (strlen(lc_ctype) == 0)
2711  lc_ctype = locale;
2712  if (strlen(lc_collate) == 0)
2713  lc_collate = locale;
2714  if (strlen(lc_numeric) == 0)
2715  lc_numeric = locale;
2716  if (strlen(lc_time) == 0)
2717  lc_time = locale;
2718  if (strlen(lc_monetary) == 0)
2719  lc_monetary = locale;
2720  if (strlen(lc_messages) == 0)
2721  lc_messages = locale;
2722  }
2723 
2724  /*
2725  * canonicalize locale names, and obtain any missing values from our
2726  * current environment
2727  */
2728 
2729  check_locale_name(LC_CTYPE, lc_ctype, &canonname);
2730  lc_ctype = canonname;
2731  check_locale_name(LC_COLLATE, lc_collate, &canonname);
2732  lc_collate = canonname;
2733  check_locale_name(LC_NUMERIC, lc_numeric, &canonname);
2734  lc_numeric = canonname;
2735  check_locale_name(LC_TIME, lc_time, &canonname);
2736  lc_time = canonname;
2737  check_locale_name(LC_MONETARY, lc_monetary, &canonname);
2738  lc_monetary = canonname;
2739 #if defined(LC_MESSAGES) && !defined(WIN32)
2740  check_locale_name(LC_MESSAGES, lc_messages, &canonname);
2741  lc_messages = canonname;
2742 #else
2743  /* when LC_MESSAGES is not available, use the LC_CTYPE setting */
2744  check_locale_name(LC_CTYPE, lc_messages, &canonname);
2745  lc_messages = canonname;
2746 #endif
2747 }
2748 
2749 /*
2750  * print help text
2751  */
2752 static void
2753 usage(const char *progname)
2754 {
2755  printf(_("%s initializes a PostgreSQL database cluster.\n\n"), progname);
2756  printf(_("Usage:\n"));
2757  printf(_(" %s [OPTION]... [DATADIR]\n"), progname);
2758  printf(_("\nOptions:\n"));
2759  printf(_(" -A, --auth=METHOD default authentication method for local connections\n"));
2760  printf(_(" --auth-host=METHOD default authentication method for local TCP/IP connections\n"));
2761  printf(_(" --auth-local=METHOD default authentication method for local-socket connections\n"));
2762  printf(_(" [-D, --pgdata=]DATADIR location for this database cluster\n"));
2763  printf(_(" -E, --encoding=ENCODING set default encoding for new databases\n"));
2764  printf(_(" --locale=LOCALE set default locale for new databases\n"));
2765  printf(_(" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n"
2766  " --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n"
2767  " set default locale in the respective category for\n"
2768  " new databases (default taken from environment)\n"));
2769  printf(_(" --no-locale equivalent to --locale=C\n"));
2770  printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
2771  printf(_(" -T, --text-search-config=CFG\n"
2772  " default text search configuration\n"));
2773  printf(_(" -U, --username=NAME database superuser name\n"));
2774  printf(_(" -W, --pwprompt prompt for a password for the new superuser\n"));
2775  printf(_(" -X, --xlogdir=XLOGDIR location for the transaction log directory\n"));
2776  printf(_("\nLess commonly used options:\n"));
2777  printf(_(" -d, --debug generate lots of debugging output\n"));
2778  printf(_(" -k, --data-checksums use data page checksums\n"));
2779  printf(_(" -L DIRECTORY where to find the input files\n"));
2780  printf(_(" -n, --noclean do not clean up after errors\n"));
2781  printf(_(" -N, --nosync do not wait for changes to be written safely to disk\n"));
2782  printf(_(" -s, --show show internal settings\n"));
2783  printf(_(" -S, --sync-only only sync data directory\n"));
2784  printf(_("\nOther options:\n"));
2785  printf(_(" -V, --version output version information, then exit\n"));
2786  printf(_(" -?, --help show this help, then exit\n"));
2787  printf(_("\nIf the data directory is not specified, the environment variable PGDATA\n"
2788  "is used.\n"));
2789  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
2790 }
2791 
2792 static void
2793 check_authmethod_unspecified(const char **authmethod)
2794 {
2795  if (*authmethod == NULL || strlen(*authmethod) == 0)
2796  {
2797  authwarning = _("\nWARNING: enabling \"trust\" authentication for local connections\n"
2798  "You can change this by editing pg_hba.conf or using the option -A, or\n"
2799  "--auth-local and --auth-host, the next time you run initdb.\n");
2800  *authmethod = "trust";
2801  }
2802 }
2803 
2804 static void
2805 check_authmethod_valid(const char *authmethod, const char **valid_methods, const char *conntype)
2806 {
2807  const char **p;
2808 
2809  for (p = valid_methods; *p; p++)
2810  {
2811  if (strcmp(authmethod, *p) == 0)
2812  return;
2813  /* with space = param */
2814  if (strchr(authmethod, ' '))
2815  if (strncmp(authmethod, *p, (authmethod - strchr(authmethod, ' '))) == 0)
2816  return;
2817  }
2818 
2819  fprintf(stderr, _("%s: invalid authentication method \"%s\" for \"%s\" connections\n"),
2820  progname, authmethod, conntype);
2821  exit(1);
2822 }
2823 
2824 static void
2826 {
2827  if ((strcmp(authmethodlocal, "md5") == 0 ||
2828  strcmp(authmethodlocal, "password") == 0) &&
2829  (strcmp(authmethodhost, "md5") == 0 ||
2830  strcmp(authmethodhost, "password") == 0) &&
2831  !(pwprompt || pwfilename))
2832  {
2833  fprintf(stderr, _("%s: must specify a password for the superuser to enable %s authentication\n"), progname,
2834  (strcmp(authmethodlocal, "md5") == 0 ||
2835  strcmp(authmethodlocal, "password") == 0)
2836  ? authmethodlocal
2837  : authmethodhost);
2838  exit(1);
2839  }
2840 }
2841 
2842 
2843 void
2845 {
2846  char *pgdata_get_env,
2847  *pgdata_set_env;
2848 
2849  if (strlen(pg_data) == 0)
2850  {
2851  pgdata_get_env = getenv("PGDATA");
2852  if (pgdata_get_env && strlen(pgdata_get_env))
2853  {
2854  /* PGDATA found */
2855  pg_data = pg_strdup(pgdata_get_env);
2856  }
2857  else
2858  {
2859  fprintf(stderr,
2860  _("%s: no data directory specified\n"
2861  "You must identify the directory where the data for this database system\n"
2862  "will reside. Do this with either the invocation option -D or the\n"
2863  "environment variable PGDATA.\n"),
2864  progname);
2865  exit(1);
2866  }
2867  }
2868 
2871 
2872  /*
2873  * we have to set PGDATA for postgres rather than pass it on the command
2874  * line to avoid dumb quoting problems on Windows, and we would especially
2875  * need quotes otherwise on Windows because paths there are most likely to
2876  * have embedded spaces.
2877  */
2878  pgdata_set_env = psprintf("PGDATA=%s", pg_data);
2879  putenv(pgdata_set_env);
2880 }
2881 
2882 
2883 void
2885 {
2886  int ret;
2887 
2888  if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
2889  backend_exec)) < 0)
2890  {
2891  char full_path[MAXPGPATH];
2892 
2893  if (find_my_exec(argv0, full_path) < 0)
2894  strlcpy(full_path, progname, sizeof(full_path));
2895 
2896  if (ret == -1)
2897  fprintf(stderr,
2898  _("The program \"postgres\" is needed by %s "
2899  "but was not found in the\n"
2900  "same directory as \"%s\".\n"
2901  "Check your installation.\n"),
2902  progname, full_path);
2903  else
2904  fprintf(stderr,
2905  _("The program \"postgres\" was found by \"%s\"\n"
2906  "but was not the same version as %s.\n"
2907  "Check your installation.\n"),
2908  full_path, progname);
2909  exit(1);
2910  }
2911 
2912  /* store binary directory */
2913  strcpy(bin_path, backend_exec);
2914  *last_dir_separator(bin_path) = '\0';
2916 
2917  if (!share_path)
2918  {
2921  }
2922  else if (!is_absolute_path(share_path))
2923  {
2924  fprintf(stderr, _("%s: input file location must be an absolute path\n"), progname);
2925  exit(1);
2926  }
2927 
2929 }
2930 
2931 void
2933 {
2934  int user_enc;
2935 
2936  setlocales();
2937 
2938  if (strcmp(lc_ctype, lc_collate) == 0 &&
2939  strcmp(lc_ctype, lc_time) == 0 &&
2940  strcmp(lc_ctype, lc_numeric) == 0 &&
2941  strcmp(lc_ctype, lc_monetary) == 0 &&
2942  strcmp(lc_ctype, lc_messages) == 0)
2943  printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
2944  else
2945  {
2946  printf(_("The database cluster will be initialized with locales\n"
2947  " COLLATE: %s\n"
2948  " CTYPE: %s\n"
2949  " MESSAGES: %s\n"
2950  " MONETARY: %s\n"
2951  " NUMERIC: %s\n"
2952  " TIME: %s\n"),
2953  lc_collate,
2954  lc_ctype,
2955  lc_messages,
2956  lc_monetary,
2957  lc_numeric,
2958  lc_time);
2959  }
2960 
2961  if (strlen(encoding) == 0)
2962  {
2963  int ctype_enc;
2964 
2965  ctype_enc = pg_get_encoding_from_locale(lc_ctype, true);
2966 
2967  if (ctype_enc == -1)
2968  {
2969  /* Couldn't recognize the locale's codeset */
2970  fprintf(stderr, _("%s: could not find suitable encoding for locale \"%s\"\n"),
2971  progname, lc_ctype);
2972  fprintf(stderr, _("Rerun %s with the -E option.\n"), progname);
2973  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2974  progname);
2975  exit(1);
2976  }
2977  else if (!pg_valid_server_encoding_id(ctype_enc))
2978  {
2979  /*
2980  * We recognized it, but it's not a legal server encoding. On
2981  * Windows, UTF-8 works with any locale, so we can fall back to
2982  * UTF-8.
2983  */
2984 #ifdef WIN32
2985  printf(_("Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n"
2986  "The default database encoding will be set to \"%s\" instead.\n"),
2987  pg_encoding_to_char(ctype_enc),
2989  ctype_enc = PG_UTF8;
2990  encodingid = encodingid_to_string(ctype_enc);
2991 #else
2992  fprintf(stderr,
2993  _("%s: locale \"%s\" requires unsupported encoding \"%s\"\n"),
2994  progname, lc_ctype, pg_encoding_to_char(ctype_enc));
2995  fprintf(stderr,
2996  _("Encoding \"%s\" is not allowed as a server-side encoding.\n"
2997  "Rerun %s with a different locale selection.\n"),
2998  pg_encoding_to_char(ctype_enc), progname);
2999  exit(1);
3000 #endif
3001  }
3002  else
3003  {
3004  encodingid = encodingid_to_string(ctype_enc);
3005  printf(_("The default database encoding has accordingly been set to \"%s\".\n"),
3006  pg_encoding_to_char(ctype_enc));
3007  }
3008  }
3009  else
3011 
3012  user_enc = atoi(encodingid);
3013  if (!check_locale_encoding(lc_ctype, user_enc) ||
3014  !check_locale_encoding(lc_collate, user_enc))
3015  exit(1); /* check_locale_encoding printed the error */
3016 
3017 }
3018 
3019 
3020 void
3022 {
3023  set_input(&bki_file, "postgres.bki");
3024  set_input(&desc_file, "postgres.description");
3025  set_input(&shdesc_file, "postgres.shdescription");
3026  set_input(&hba_file, "pg_hba.conf.sample");
3027  set_input(&ident_file, "pg_ident.conf.sample");
3028  set_input(&conf_file, "postgresql.conf.sample");
3029  set_input(&conversion_file, "conversion_create.sql");
3030  set_input(&dictionary_file, "snowball_create.sql");
3031  set_input(&info_schema_file, "information_schema.sql");
3032  set_input(&features_file, "sql_features.txt");
3033  set_input(&system_views_file, "system_views.sql");
3034 
3035  if (show_setting || debug)
3036  {
3037  fprintf(stderr,
3038  "VERSION=%s\n"
3039  "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
3040  "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
3041  "POSTGRES_DESCR=%s\nPOSTGRES_SHDESCR=%s\n"
3042  "POSTGRESQL_CONF_SAMPLE=%s\n"
3043  "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
3044  PG_VERSION,
3046  username, bki_file,
3048  conf_file,
3049  hba_file, ident_file);
3050  if (show_setting)
3051  exit(0);
3052  }
3053 
3065 }
3066 
3067 
3068 void
3070 {
3071  if (strlen(default_text_search_config) == 0)
3072  {
3075  {
3076  printf(_("%s: could not find suitable text search configuration for locale \"%s\"\n"),
3077  progname, lc_ctype);
3078  default_text_search_config = "simple";
3079  }
3080  }
3081  else
3082  {
3083  const char *checkmatch = find_matching_ts_config(lc_ctype);
3084 
3085  if (checkmatch == NULL)
3086  {
3087  printf(_("%s: warning: suitable text search configuration for locale \"%s\" is unknown\n"),
3088  progname, lc_ctype);
3089  }
3090  else if (strcmp(checkmatch, default_text_search_config) != 0)
3091  {
3092  printf(_("%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n"),
3094  }
3095  }
3096 
3097  printf(_("The default text search configuration will be set to \"%s\".\n"),
3099 
3100 }
3101 
3102 
3103 void
3105 {
3106  /* some of these are not valid on Windows */
3107 #ifdef SIGHUP
3109 #endif
3110 #ifdef SIGINT
3111  pqsignal(SIGINT, trapsig);
3112 #endif
3113 #ifdef SIGQUIT
3115 #endif
3116 #ifdef SIGTERM
3117  pqsignal(SIGTERM, trapsig);
3118 #endif
3119 
3120  /* Ignore SIGPIPE when writing to backend, so we can clean up */
3121 #ifdef SIGPIPE
3123 #endif
3124 
3125  /* Prevent SIGSYS so we can probe for kernel calls that might not work */
3126 #ifdef SIGSYS
3127  pqsignal(SIGSYS, SIG_IGN);
3128 #endif
3129 }
3130 
3131 
3132 void
3134 {
3135  int ret;
3136 
3137  switch ((ret = pg_check_dir(pg_data)))
3138  {
3139  case 0:
3140  /* PGDATA not there, must create it */
3141  printf(_("creating directory %s ... "),
3142  pg_data);
3143  fflush(stdout);
3144 
3145  if (!mkdatadir(NULL))
3146  exit_nicely();
3147  else
3148  check_ok();
3149 
3150  made_new_pgdata = true;
3151  break;
3152 
3153  case 1:
3154  /* Present but empty, fix permissions and use it */
3155  printf(_("fixing permissions on existing directory %s ... "),
3156  pg_data);
3157  fflush(stdout);
3158 
3159  if (chmod(pg_data, S_IRWXU) != 0)
3160  {
3161  fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
3162  progname, pg_data, strerror(errno));
3163  exit_nicely();
3164  }
3165  else
3166  check_ok();
3167 
3168  found_existing_pgdata = true;
3169  break;
3170 
3171  case 2:
3172  case 3:
3173  case 4:
3174  /* Present and not empty */
3175  fprintf(stderr,
3176  _("%s: directory \"%s\" exists but is not empty\n"),
3177  progname, pg_data);
3178  if (ret != 4)
3179  warn_on_mount_point(ret);
3180  else
3181  fprintf(stderr,
3182  _("If you want to create a new database system, either remove or empty\n"
3183  "the directory \"%s\" or run %s\n"
3184  "with an argument other than \"%s\".\n"),
3186  exit(1); /* no further message needed */
3187 
3188  default:
3189  /* Trouble accessing directory */
3190  fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
3191  progname, pg_data, strerror(errno));
3192  exit_nicely();
3193  }
3194 }
3195 
3196 
3197 void
3199 {
3200  /* Create transaction log symlink, if required */
3201  if (strcmp(xlog_dir, "") != 0)
3202  {
3203  char *linkloc;
3204  int ret;
3205 
3206  /* clean up xlog directory name, check it's absolute */
3208  if (!is_absolute_path(xlog_dir))
3209  {
3210  fprintf(stderr, _("%s: transaction log directory location must be an absolute path\n"), progname);
3211  exit_nicely();
3212  }
3213 
3214  /* check if the specified xlog directory exists/is empty */
3215  switch ((ret = pg_check_dir(xlog_dir)))
3216  {
3217  case 0:
3218  /* xlog directory not there, must create it */
3219  printf(_("creating directory %s ... "),
3220  xlog_dir);
3221  fflush(stdout);
3222 
3223  if (pg_mkdir_p(xlog_dir, S_IRWXU) != 0)
3224  {
3225  fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
3226  progname, xlog_dir, strerror(errno));
3227  exit_nicely();
3228  }
3229  else
3230  check_ok();
3231 
3232  made_new_xlogdir = true;
3233  break;
3234 
3235  case 1:
3236  /* Present but empty, fix permissions and use it */
3237  printf(_("fixing permissions on existing directory %s ... "),
3238  xlog_dir);
3239  fflush(stdout);
3240 
3241  if (chmod(xlog_dir, S_IRWXU) != 0)
3242  {
3243  fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
3244  progname, xlog_dir, strerror(errno));
3245  exit_nicely();
3246  }
3247  else
3248  check_ok();
3249 
3250  found_existing_xlogdir = true;
3251  break;
3252 
3253  case 2:
3254  case 3:
3255  case 4:
3256  /* Present and not empty */
3257  fprintf(stderr,
3258  _("%s: directory \"%s\" exists but is not empty\n"),
3259  progname, xlog_dir);
3260  if (ret != 4)
3261  warn_on_mount_point(ret);
3262  else
3263  fprintf(stderr,
3264  _("If you want to store the transaction log there, either\n"
3265  "remove or empty the directory \"%s\".\n"),
3266  xlog_dir);
3267  exit_nicely();
3268 
3269  default:
3270  /* Trouble accessing directory */
3271  fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
3272  progname, xlog_dir, strerror(errno));
3273  exit_nicely();
3274  }
3275 
3276  /* form name of the place where the symlink must go */
3277  linkloc = psprintf("%s/pg_xlog", pg_data);
3278 
3279 #ifdef HAVE_SYMLINK
3280  if (symlink(xlog_dir, linkloc) != 0)
3281  {
3282  fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
3283  progname, linkloc, strerror(errno));
3284  exit_nicely();
3285  }
3286 #else
3287  fprintf(stderr, _("%s: symlinks are not supported on this platform"));
3288  exit_nicely();
3289 #endif
3290  free(linkloc);
3291  }
3292 }
3293 
3294 
3295 void
3297 {
3298  if (error == 2)
3299  fprintf(stderr,
3300  _("It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n"));
3301  else if (error == 3)
3302  fprintf(stderr,
3303  _("It contains a lost+found directory, perhaps due to it being a mount point.\n"));
3304 
3305  fprintf(stderr,
3306  _("Using a mount point directly as the data directory is not recommended.\n"
3307  "Create a subdirectory under the mount point.\n"));
3308 }
3309 
3310 
3311 void
3313 {
3314  int i;
3315 
3316  setup_signals();
3317 
3318  umask(S_IRWXG | S_IRWXO);
3319 
3321 
3323 
3324  /* Create required subdirectories */
3325  printf(_("creating subdirectories ... "));
3326  fflush(stdout);
3327 
3328  for (i = 0; i < (sizeof(subdirs) / sizeof(char *)); i++)
3329  {
3330  if (!mkdatadir(subdirs[i]))
3331  exit_nicely();
3332  }
3333 
3334  check_ok();
3335 
3336  /* Top level PG_VERSION is checked by bootstrapper, so make it first */
3338 
3339  /* Select suitable configuration settings */
3340  set_null_conf();
3342 
3343  /* Now create all the text config files */
3344  setup_config();
3345 
3346  /* Bootstrap template1 */
3348 
3349  /*
3350  * Make the per-database PG_VERSION for template1 only after init'ing it
3351  */
3352  write_version_file("base/1");
3353 
3354  /* Create the stuff we don't need to use bootstrap mode for */
3355 
3356  setup_auth();
3357  if (pwprompt || pwfilename)
3358  get_set_pwd();
3359 
3360  setup_depend();
3361 
3362  setup_sysviews();
3363 
3365 
3366  setup_collation();
3367 
3368  setup_conversion();
3369 
3370  setup_dictionary();
3371 
3372  setup_privileges();
3373 
3374  setup_schema();
3375 
3376  load_plpgsql();
3377 
3378  vacuum_db();
3379 
3380  make_template0();
3381 
3382  make_postgres();
3383 }
3384 
3385 
3386 int
3387 main(int argc, char *argv[])
3388 {
3389  static struct option long_options[] = {
3390  {"pgdata", required_argument, NULL, 'D'},
3391  {"encoding", required_argument, NULL, 'E'},
3392  {"locale", required_argument, NULL, 1},
3393  {"lc-collate", required_argument, NULL, 2},
3394  {"lc-ctype", required_argument, NULL, 3},
3395  {"lc-monetary", required_argument, NULL, 4},
3396  {"lc-numeric", required_argument, NULL, 5},
3397  {"lc-time", required_argument, NULL, 6},
3398  {"lc-messages", required_argument, NULL, 7},
3399  {"no-locale", no_argument, NULL, 8},
3400  {"text-search-config", required_argument, NULL, 'T'},
3401  {"auth", required_argument, NULL, 'A'},
3402  {"auth-local", required_argument, NULL, 10},
3403  {"auth-host", required_argument, NULL, 11},
3404  {"pwprompt", no_argument, NULL, 'W'},
3405  {"pwfile", required_argument, NULL, 9},
3406  {"username", required_argument, NULL, 'U'},
3407  {"help", no_argument, NULL, '?'},
3408  {"version", no_argument, NULL, 'V'},
3409  {"debug", no_argument, NULL, 'd'},
3410  {"show", no_argument, NULL, 's'},
3411  {"noclean", no_argument, NULL, 'n'},
3412  {"nosync", no_argument, NULL, 'N'},
3413  {"sync-only", no_argument, NULL, 'S'},
3414  {"xlogdir", required_argument, NULL, 'X'},
3415  {"data-checksums", no_argument, NULL, 'k'},
3416  {NULL, 0, NULL, 0}
3417  };
3418 
3419  /*
3420  * options with no short version return a low integer, the rest return
3421  * their short version value
3422  */
3423  int c;
3424  int option_index;
3425  char *effective_user;
3426  char bin_dir[MAXPGPATH];
3427 
3428  /*
3429  * Ensure that buffering behavior of stdout and stderr matches what it is
3430  * in interactive usage (at least on most platforms). This prevents
3431  * unexpected output ordering when, eg, output is redirected to a file.
3432  * POSIX says we must do this before any other usage of these files.
3433  */
3434  setvbuf(stdout, NULL, PG_IOLBF, 0);
3435  setvbuf(stderr, NULL, _IONBF, 0);
3436 
3437  progname = get_progname(argv[0]);
3438  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb"));
3439 
3440  if (argc > 1)
3441  {
3442  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
3443  {
3444  usage(progname);
3445  exit(0);
3446  }
3447  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
3448  {
3449  puts("initdb (PostgreSQL) " PG_VERSION);
3450  exit(0);
3451  }
3452  }
3453 
3454  /* process command-line options */
3455 
3456  while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
3457  {
3458  switch (c)
3459  {
3460  case 'A':
3462 
3463  /*
3464  * When ident is specified, use peer for local connections.
3465  * Mirrored, when peer is specified, use ident for TCP/IP
3466  * connections.
3467  */
3468  if (strcmp(authmethodhost, "ident") == 0)
3469  authmethodlocal = "peer";
3470  else if (strcmp(authmethodlocal, "peer") == 0)
3471  authmethodhost = "ident";
3472  break;
3473  case 10:
3475  break;
3476  case 11:
3478  break;
3479  case 'D':
3481  break;
3482  case 'E':
3484  break;
3485  case 'W':
3486  pwprompt = true;
3487  break;
3488  case 'U':
3490  break;
3491  case 'd':
3492  debug = true;
3493  printf(_("Running in debug mode.\n"));
3494  break;
3495  case 'n':
3496  noclean = true;
3497  printf(_("Running in noclean mode. Mistakes will not be cleaned up.\n"));
3498  break;
3499  case 'N':
3500  do_sync = false;
3501  break;
3502  case 'S':
3503  sync_only = true;
3504  break;
3505  case 'k':
3506  data_checksums = true;
3507  break;
3508  case 'L':
3510  break;
3511  case 1:
3512  locale = pg_strdup(optarg);
3513  break;
3514  case 2:
3516  break;
3517  case 3:
3519  break;
3520  case 4:
3522  break;
3523  case 5:
3525  break;
3526  case 6:
3528  break;
3529  case 7:
3531  break;
3532  case 8:
3533  locale = "C";
3534  break;
3535  case 9:
3537  break;
3538  case 's':
3539  show_setting = true;
3540  break;
3541  case 'T':
3543  break;
3544  case 'X':
3546  break;
3547  default:
3548  /* getopt_long already emitted a complaint */
3549  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
3550  progname);
3551  exit(1);
3552  }
3553  }
3554 
3555 
3556  /*
3557  * Non-option argument specifies data directory as long as it wasn't
3558  * already specified with -D / --pgdata
3559  */
3560  if (optind < argc && strlen(pg_data) == 0)
3561  {
3562  pg_data = pg_strdup(argv[optind]);
3563  optind++;
3564  }
3565 
3566  if (optind < argc)
3567  {
3568  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
3569  progname, argv[optind]);
3570  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
3571  progname);
3572  exit(1);
3573  }
3574 
3575  /* If we only need to fsync, just to it and exit */
3576  if (sync_only)
3577  {
3578  setup_pgdata();
3579  perform_fsync();
3580  return 0;
3581  }
3582 
3583  if (pwprompt && pwfilename)
3584  {
3585  fprintf(stderr, _("%s: password prompt and password file cannot be specified together\n"), progname);
3586  exit(1);
3587  }
3588 
3591 
3594 
3596 
3598 
3599  setup_pgdata();
3600 
3601  setup_bin_paths(argv[0]);
3602 
3603  effective_user = get_id();
3604  if (strlen(username) == 0)
3605  username = effective_user;
3606 
3607  printf(_("The files belonging to this database system will be owned "
3608  "by user \"%s\".\n"
3609  "This user must also own the server process.\n\n"),
3610  effective_user);
3611 
3612  set_info_version();
3613 
3615 
3617 
3619 
3620  printf("\n");
3621 
3622  if (data_checksums)
3623  printf(_("Data page checksums are enabled.\n"));
3624  else
3625  printf(_("Data page checksums are disabled.\n"));
3626 
3627  printf("\n");
3628 
3630 
3631  if (do_sync)
3632  perform_fsync();
3633  else
3634  printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n"));
3635 
3636  if (authwarning != NULL)
3637  fprintf(stderr, "%s", authwarning);
3638 
3639  /* Get directory specification used to start this executable */
3640  strlcpy(bin_dir, argv[0], sizeof(bin_dir));
3641  get_parent_directory(bin_dir);
3642 
3643  printf(_("\nSuccess. You can now start the database server using:\n\n"
3644  " %s%s%spg_ctl%s -D %s%s%s -l logfile start\n\n"),
3645  QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
3647 
3648  return 0;
3649 }
static char * lc_monetary
Definition: initdb.c:111
#define DIR_SEP
Definition: initdb.c:316
static const char * find_matching_ts_config(const char *lc_type)
Definition: initdb.c:916
#define getaddrinfo
Definition: getaddrinfo.h:138
static void write_version_file(char *extrapath)
Definition: initdb.c:1035
static void skip(struct vars *v)
Definition: regc_lex.c:1081
void setup_data_file_paths(void)
Definition: initdb.c:3021
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
Definition: exec.c:307
static void setup_conversion(void)
Definition: initdb.c:2084
#define MIN_BUFS_FOR_CONNS(nconns)
#define PG_CMD_PRINTF3(fmt, arg1, arg2, arg3)
Definition: initdb.c:308
static char ** replace_token(char **lines, const char *token, const char *replacement)
Definition: initdb.c:343
static char * argv0
Definition: pg_ctl.c:96
static char * choose_dsm_implementation(void)
Definition: initdb.c:1100
void setup_locale_encoding(void)
Definition: initdb.c:2932
static void check_authmethod_valid(const char *authmethod, const char **valid_methods, const char *conntype)
Definition: initdb.c:2805
static void make_template0(void)
Definition: initdb.c:2340
static FILE * popen_check(const char *command, const char *mode)
Definition: initdb.c:734
static char infoversion[100]
Definition: initdb.c:148
static bool debug
Definition: initdb.c:121
int system(const char *command)
Definition: system.c:52
static char * system_views_file
Definition: initdb.c:143
static void error(void)
Definition: sql-dyntest.c:147
static char * lc_collate
Definition: initdb.c:109
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
void create_xlog_symlink(void)
Definition: initdb.c:3198
static char * encodingid_to_string(int enc)
Definition: initdb.c:839
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void warn_on_mount_point(int error)
Definition: initdb.c:3296
static char * conf_file
Definition: initdb.c:138
const char * get_progname(const char *argv0)
Definition: path.c:419
static const char * backend_options
Definition: initdb.c:180
static void vacuum_db(void)
Definition: initdb.c:2314
int pg_valid_server_encoding(const char *name)
Definition: encnames.c:425
static void get_set_pwd(void)
Definition: initdb.c:1614
static void setup_schema(void)
Definition: initdb.c:2231
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
long random(void)
Definition: random.c:22
static char * features_file
Definition: initdb.c:142
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static void walkdir(char *path, void(*action)(char *fname, bool isdir))
Definition: initdb.c:524
static void setup_depend(void)
Definition: initdb.c:1699
static bool made_new_xlogdir
Definition: initdb.c:146
#define AUTHTRUST_WARNING
Definition: initdb.c:162
void canonicalize_path(char *path)
Definition: path.c:220
static bool caught_signal
Definition: initdb.c:149
int closedir(DIR *)
Definition: dirent.c:113
#define PG_BACKEND_VERSIONSTR
Definition: miscadmin.h:29
int pg_valid_server_encoding_id(int encoding)
Definition: encnames.c:439
static void setup_collation(void)
Definition: initdb.c:1933
static void bootstrap_template1(void)
Definition: initdb.c:1480
#define PG_BINARY_W
Definition: c.h:1030
static void pre_sync_fname(char *fname, bool isdir)
Definition: initdb.c:637
static void exit_nicely(void)
Definition: initdb.c:753
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void setup_signals(void)
Definition: initdb.c:3104
static const struct tsearch_config_match tsearch_config_languages[]
Definition: initdb.c:875
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
static bool pwprompt
Definition: initdb.c:117
static char * pgdata_native
Definition: initdb.c:152
#define PG_CMD_PUTS(line)
Definition: initdb.c:290
#define putenv(x)
Definition: win32.h:403
#define AI_NUMERICHOST
Definition: getaddrinfo.h:75
static chr newline(void)
Definition: regc_lex.c:1109
static void setup_auth(void)
Definition: initdb.c:1579
Definition: dirent.h:9
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1027
#define SIGQUIT
Definition: win32.h:183
static char * get_id(void)
Definition: initdb.c:816
static char * share_path
Definition: initdb.c:103
static const char * subdirs[]
Definition: initdb.c:182
static char * encodingid
Definition: initdb.c:132
static struct pg_tm tm
Definition: localtime.c:116
void get_restricted_token(const char *progname)
static void set_null_conf(void)
Definition: initdb.c:1066
static const char * authmethodlocal
Definition: initdb.c:120
static void setup_sysviews(void)
Definition: initdb.c:1796
#define NAMEDATALEN
static char * lc_time
Definition: initdb.c:113
static void load_plpgsql(void)
Definition: initdb.c:2289
static void check_input(char *path)
Definition: initdb.c:994
static int n_connections
Definition: initdb.c:155
static void check_authmethod_unspecified(const char **authmethod)
Definition: initdb.c:2793
char * escape_single_quotes_ascii(const char *src)
Definition: quotes.c:33
#define required_argument
Definition: getopt_long.h:25
char * Pointer
Definition: c.h:218
#define SIG_IGN
Definition: win32.h:179
int optind
Definition: getopt.c:51
#define IS_HIGHBIT_SET(ch)
Definition: c.h:958
#define PG_CMD_DECL
Definition: initdb.c:275
Definition: dirent.c:25
static void make_postgres(void)
Definition: initdb.c:2393
struct pg_encoding enc
Definition: encode.c:522
static const char * auth_methods_host[]
Definition: initdb.c:74
static char * lc_messages
Definition: initdb.c:114
static char * desc_file
Definition: initdb.c:134
#define MAXPGPATH
static bool check_locale_encoding(const char *locale, int encoding)
Definition: initdb.c:2666
static const char * default_text_search_config
Definition: initdb.c:115
static char * lc_ctype
Definition: initdb.c:110
#define PG_CMD_OPEN
Definition: initdb.c:277
static char * conversion_file
Definition: initdb.c:139
const char * tsconfname
Definition: initdb.c:871
static void setup_config(void)
Definition: initdb.c:1240
static char * lc_numeric
Definition: initdb.c:112
DIR * opendir(const char *)
Definition: dirent.c:33
static void walktblspc_links(char *path, void(*action)(char *fname, bool isdir))
Definition: initdb.c:589
int find_my_exec(const char *argv0, char *retpath)
Definition: exec.c:119
static bool found_existing_pgdata
Definition: initdb.c:145
char * ai_canonname
Definition: getaddrinfo.h:108
char * c
static char * buf
Definition: pg_test_fsync.c:65
void initialize_data_directory(void)
Definition: initdb.c:3312
#define is_absolute_path(filename)
Definition: port.h:76
#define PG_CMD_PRINTF1(fmt, arg1)
Definition: initdb.c:296
void get_parent_directory(char *path)
Definition: path.c:820
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
unsigned int uint32
Definition: c.h:241
static void setup_privileges(void)
Definition: initdb.c:2164
static char * pg_data
Definition: initdb.c:106
#define DEVNULL
Definition: port.h:115
static char * pwfilename
Definition: initdb.c:118
static void check_ok(void)
Definition: initdb.c:2505
#define fsync(fd)
Definition: win32.h:56
static bool found_existing_xlogdir
Definition: initdb.c:147
static bool made_new_pgdata
Definition: initdb.c:144
char * simple_prompt(const char *prompt, int maxlen, bool echo)
Definition: sprompt.c:38
static char * dictionary_file
Definition: initdb.c:140
#define DATEORDER_YMD
Definition: miscadmin.h:214
static void test_config_settings(void)
Definition: initdb.c:1140
static void setup_dictionary(void)
Definition: initdb.c:2119
const char * select_default_timezone(const char *share_path)
void setup_bin_paths(const char *argv0)
Definition: initdb.c:2884
static const char * progname
Definition: initdb.c:131
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:36
void create_data_directory(void)
Definition: initdb.c:3133
#define PG_CMD_CLOSE
Definition: initdb.c:284
#define no_argument
Definition: getopt_long.h:24
static void set_input(char **dest, char *filename)
Definition: initdb.c:985
static const char * boot_options
Definition: initdb.c:179
static char * xlog_dir
Definition: initdb.c:127
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1001
static bool data_checksums
Definition: initdb.c:126
static char * info_schema_file
Definition: initdb.c:141
static size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm)
Definition: initdb.c:2530
static int locale_date_order(const char *locale)
Definition: initdb.c:2539
char * last_dir_separator(const char *filename)
Definition: path.c:134
#define PG_IOLBF
Definition: port.h:338
#define SIGPIPE
Definition: win32.h:187
#define S_IRWXO
Definition: win32.h:466
#define DATEORDER_DMY
Definition: miscadmin.h:215
#define SIGHUP
Definition: win32.h:182
static char * username
Definition: initdb.c:116
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:406
static char * get_encoding_id(char *encoding_name)
Definition: initdb.c:851
#define DATEORDER_MDY
Definition: miscadmin.h:216
static void infile(const char *filename)
Definition: zic.c:825
static void setup_description(void)
Definition: initdb.c:1834
static char * encoding
Definition: initdb.c:107
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:167
#define free(a)
Definition: header.h:60
int ai_protocol
Definition: getaddrinfo.h:105
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:531
static char * authwarning
Definition: initdb.c:167
void setup_text_search(void)
Definition: initdb.c:3069
static void fsync_fname(char *fname, bool isdir)
Definition: initdb.c:682
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:293
#define NULL
Definition: c.h:202
static char ** filter_lines_with_token(char **lines, const char *token)
Definition: initdb.c:399
static bool mkdatadir(const char *subdir)
Definition: initdb.c:962
static bool do_sync
Definition: initdb.c:123
int ai_socktype
Definition: getaddrinfo.h:104
int main(int argc, char *argv[])
Definition: initdb.c:3387
static bool output_failed
Definition: initdb.c:150
static void setlocales(void)
Definition: initdb.c:2702
struct dirent * readdir(DIR *)
Definition: dirent.c:78
#define QUOTE_PATH
Definition: initdb.c:315
#define unsetenv(x)
Definition: win32.h:404
static void check_locale_name(int category, const char *locale, char **canonname)
Definition: initdb.c:2602
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
const char * name
Definition: encode.c:521
#define S_IRWXG
Definition: win32.h:462
static int n_buffers
Definition: initdb.c:156
static char * escape_quotes(const char *src)
Definition: initdb.c:323
static int output_errno
Definition: initdb.c:151
static char * filename
Definition: pg_dumpall.c:85
struct addrinfo * ai_next
Definition: getaddrinfo.h:109
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
static void perform_fsync(void)
Definition: initdb.c:2425
static void writefile(char *path, char **lines)
Definition: initdb.c:488
char * optarg
Definition: getopt.c:53
int pg_check_dir(const char *dir)
Definition: pgcheckdir.c:31
static char bin_path[MAXPGPATH]
Definition: initdb.c:209
static void usage(const char *progname)
Definition: initdb.c:2753
int i
const char * strerror(int errnum)
Definition: strerror.c:19
static void check_need_password(const char *authmethodlocal, const char *authmethodhost)
Definition: initdb.c:2825
static char backend_exec[MAXPGPATH]
Definition: initdb.c:210
static const char * auth_methods_local[]
Definition: initdb.c:91
static char * ident_file
Definition: initdb.c:137
static char * locale
Definition: initdb.c:108
static char ** readfile(const char *path)
Definition: initdb.c:426
static char * shdesc_file
Definition: initdb.c:135
static char * bki_file
Definition: initdb.c:133
static char * dynamic_shared_memory_type
Definition: initdb.c:157
static const char * authmethodhost
Definition: initdb.c:119
size_t ai_addrlen
Definition: getaddrinfo.h:106
static bool sync_only
Definition: initdb.c:124
char d_name[MAX_PATH]
Definition: dirent.h:14
static char version_file[MAXPGPATH]
Definition: pg_ctl.c:101
#define close(a)
Definition: win32.h:17
int ai_flags
Definition: getaddrinfo.h:102
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
void get_share_path(const char *my_exec_path, char *ret_path)
Definition: path.c:670
#define PG_CMD_PRINTF2(fmt, arg1, arg2)
Definition: initdb.c:302
#define lstat(path, sb)
Definition: win32.h:258
void setup_pgdata(void)
Definition: initdb.c:2844
#define _(x)
Definition: elog.c:83
const char * langname
Definition: initdb.c:872
static void trapsig(int signum)
Definition: initdb.c:2494
struct sockaddr * ai_addr
Definition: getaddrinfo.h:107
static char * hba_file
Definition: initdb.c:136
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:234
static void set_info_version(void)
Definition: initdb.c:2204
#define DEFAULT_PGSOCKET_DIR
static bool show_setting
Definition: initdb.c:125
static bool noclean
Definition: initdb.c:122
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:76
int ai_family
Definition: getaddrinfo.h:103