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