*
* template0 is made just by copying the completed template1.
*
- *
- * TODO:
- * - clean up find_postgres code and return values
- *
* Note:
* The program has some memory leakage - it isn't worth cleaning it up.
*
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
+ * Portions taken from FreeBSD.
*
- * $Header: /cvsroot/pgsql/src/bin/initdb/initdb.c,v 1.8 2003/11/14 17:19:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.45 2004/08/01 05:59:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
#include <locale.h>
#include <signal.h>
+#include <errno.h>
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
#include "libpq/pqsignal.h"
#include "mb/pg_wchar.h"
#endif
+#define _(x) gettext((x))
+
/* version string we expect back from postgres */
#define PG_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
/*
* these values are passed in by makefile defines
- *
- * Note that "datadir" is not the directory we're going to initialize,
- * it's merely how Autoconf names PREFIX/share.
*/
-char *bindir = PGBINDIR;
-char *datadir = PGDATADIR;
+char *share_path = NULL;
/* values to be obtained from arguments */
char *pg_data = "";
char *lc_messages = "";
char *username = "";
bool pwprompt = false;
+char *pwfilename = NULL;
+char *authmethod = "";
bool debug = false;
bool noclean = false;
-bool show_help = false;
-bool show_version = false;
bool show_setting = false;
/* internal vars */
-char *progname;
-char *self_path;
+const char *progname;
char *postgres;
char *encodingid = "0";
char *bki_file;
char *effective_user;
bool testpath = true;
bool made_new_pgdata = false;
+bool found_existing_pgdata = false;
char infoversion[100];
-bool not_ok = false;
+bool caught_signal = false;
+bool output_failed = false;
/* defaults */
int n_connections = 10;
int n_buffers = 50;
+/*
+ * Warning messages for authentication methods
+ */
+char *authtrust_warning = \
+ "# CAUTION: Configuring the system for local \"trust\" authentication allows\n"
+ "# any local user to connect as any PostgreSQL user, including the database\n"
+ "# superuser. If you do not trust all your local users, use another\n"
+ "# authenication method.\n";
+char *authwarning = NULL;
+
/*
* Centralized knowledge of switches to pass to backend
*
static const char *backend_options = "-F -O -c search_path=pg_catalog -c exit_on_error=true";
-/* platform specific path stuff */
-#if defined(__CYGWIN__) || defined(WIN32)
-#define EXE ".exe"
-#define DEVNULL "nul"
-#else
-#define EXE ""
-#define DEVNULL "/dev/null"
-#endif
-
-#ifdef WIN32
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
-/* detected path to postgres and (we assume) friends */
-char *pgpath;
+/* path to 'initdb' binary directory */
+char bin_path[MAXPGPATH];
+char backend_exec[MAXPGPATH];
-/* forward declare all our functions */
-static bool rmtree(char *, bool);
+static void *xmalloc(size_t size);
+static char *xstrdup(const char *s);
+static bool rmtree(char *path, bool rmtopdir);
+static char **replace_token(char **lines, char *token, char *replacement);
+static char **readfile(char *path);
+static void writefile(char *path, char **lines);
+static int mkdir_p(char *path, mode_t omode);
static void exit_nicely(void);
-static void canonicalize_path(char *);
-#ifdef WIN32
-static char *expanded_path(char *);
-#else
-#define expanded_path(x) (x)
-#endif
-static char **readfile(char *);
-static void writefile(char *, char **);
static char *get_id(void);
-static char *get_encoding_id(char *);
+static char *get_encoding_id(char *encoding_name);
static char *get_short_version(void);
-static int mkdir_p(char *, mode_t);
-static int check_data_dir(void);
-static bool mkdatadir(char *);
-static bool chklocale(const char *);
-static void setlocales(void);
-static void set_input(char **, char *);
+static int check_data_dir(void);
+static bool mkdatadir(const char *subdir);
+static void set_input(char **dest, char *filename);
static void check_input(char *path);
-static int find_postgres(char *);
-static int set_paths(void);
-static char **replace_token(char **, char *, char *);
-static void set_short_version(char *, char *);
+static void set_short_version(char *short_version, char *extrapath);
static void set_null_conf(void);
-static void test_buffers(void);
static void test_connections(void);
+static void test_buffers(void);
static void setup_config(void);
-static void bootstrap_template1(char *);
+static void bootstrap_template1(char *short_version);
static void setup_shadow(void);
static void get_set_pwd(void);
static void unlimit_systables(void);
static void setup_schema(void);
static void vacuum_db(void);
static void make_template0(void);
-static void usage(void);
-static void trapsig(int);
+static void trapsig(int signum);
static void check_ok(void);
-static char *xstrdup(const char *);
-static void *xmalloc(size_t);
+static bool chklocale(const char *locale);
+static void setlocales(void);
+static void usage(const char *progname);
+
/*
* macros for running pipes to postgres
#define PG_CMD_OPEN \
do { \
- pg = popen(cmd,PG_BINARY_W); \
- if (pg == NULL) \
- exit_nicely(); \
+ fflush(stdout); \
+ fflush(stderr); \
+ pg = popen(cmd, "w"); \
+ if (pg == NULL) \
+ exit_nicely(); \
} while (0)
#define PG_CMD_CLOSE \
do { \
- if ((pclose(pg) >> 8) & 0xff) \
- exit_nicely(); \
+ if (pclose_check(pg)) \
+ exit_nicely(); \
} while (0)
#define PG_CMD_PUTLINE \
do { \
- if (fputs(*line, pg) < 0) \
- exit_nicely(); \
- fflush(pg); \
+ if (fputs(*line, pg) < 0 || fflush(pg) < 0) \
+ output_failed = true; \
} while (0)
#ifndef WIN32
result = malloc(size);
if (!result)
{
- fputs("malloc failure - bailing out\n", stderr);
+ fprintf(stderr, _("%s: out of memory\n"), progname);
exit(1);
}
return result;
result = strdup(s);
if (!result)
{
- fputs("strdup failure - bailing out\n", stderr);
+ fprintf(stderr, _("%s: out of memory\n"), progname);
exit(1);
}
return result;
}
-/*
- * make all paths look like unix, with forward slashes
- * also strip any trailing slash.
- *
- * The Windows command processor will accept suitably quoted paths
- * with forward slashes, but barfs badly with mixed forward and back
- * slashes. Removing the trailing slash on a path means we never get
- * ugly double slashes. Don't remove a leading slash, though.
- */
-static void
-canonicalize_path(char *path)
-{
- char *p;
-
- for (p = path; *p; p++)
- {
-#ifdef WIN32
- if (*p == '\\')
- *p = '/';
-#endif
- }
- if (p > path+1 && *--p == '/')
- *p = '\0';
-}
-
/*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
if ((infile = fopen(path, "r")) == NULL)
{
- fprintf(stderr, "could not read %s\n", path);
+ fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
+ progname, path, strerror(errno));
exit_nicely();
}
FILE *out_file;
char **line;
- ;
if ((out_file = fopen(path, PG_BINARY_W)) == NULL)
{
- fprintf(stderr, "could not write %s\n", path);
+ fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
+ progname, path, strerror(errno));
exit_nicely();
}
for (line = lines; *line != NULL; line++)
else if (p[0] != '/')
continue;
*p = '\0';
- if (p[1] == '\0')
+ if (!last && p[1] == '\0')
last = 1;
if (first)
{
static void
exit_nicely(void)
{
- fprintf(stderr, "%s: failed\n", progname);
+ fprintf(stderr, _("%s: failed\n"), progname);
if (!noclean)
{
if (made_new_pgdata)
{
- fprintf(stderr, "%s: removing data directory \"%s\"\n",
+ fprintf(stderr, _("%s: removing data directory \"%s\"\n"),
progname, pg_data);
if (!rmtree(pg_data, true))
- fprintf(stderr, "%s: failed\n", progname);
+ fprintf(stderr, _("%s: failed\n"), progname);
}
- else
+ else if (found_existing_pgdata)
{
fprintf(stderr,
- "%s: removing contents of data directory \"%s\"\n",
+ _("%s: removing contents of data directory \"%s\"\n"),
progname, pg_data);
if (!rmtree(pg_data, false))
- fprintf(stderr, "%s: failed\n", progname);
+ fprintf(stderr, _("%s: failed\n"), progname);
}
+ /* otherwise died during startup, do nothing! */
}
else
{
- fprintf(stderr,
- "%s: data directory \"%s\" not removed at user's request\n",
- progname, pg_data);
+ if (made_new_pgdata || found_existing_pgdata)
+ fprintf(stderr,
+ _("%s: data directory \"%s\" not removed at user's request\n"),
+ progname, pg_data);
}
+
exit(1);
}
/*
- * find the current user using code lifted from pg_id.c
+ * find the current user
*
* on unix make sure it isn't really root
*/
if (!geteuid()) /* 0 is root's uid */
{
fprintf(stderr,
- "%s: cannot be run as root\n"
+ _("%s: cannot be run as root\n"
"Please log in (using, e.g., \"su\") as the "
"(unprivileged) user that will\n"
- "own the server process.\n",
+ "own the server process.\n"),
progname);
exit(1);
}
return xstrdup(pw->pw_name);
}
+static char *
+encodingid_to_string(int enc)
+{
+ char result[20];
+
+ sprintf(result, "%d", enc);
+ return xstrdup(result);
+}
+
/*
* get the encoding id for a given encoding name
*/
get_encoding_id(char *encoding_name)
{
int enc;
- char result[20];
if (encoding_name && *encoding_name)
{
if ((enc = pg_char_to_encoding(encoding_name)) >= 0 &&
pg_valid_server_encoding(encoding_name) >= 0)
{
- sprintf(result, "%d", enc);
- return xstrdup(result);
+ return encodingid_to_string(enc);
}
}
- fprintf(stderr, "%s: \"%s\" is not a valid server encoding name\n",
+ fprintf(stderr, _("%s: \"%s\" is not a valid server encoding name\n"),
progname, encoding_name ? encoding_name : "(null)");
exit(1);
}
+#ifdef HAVE_LANGINFO_H
+/*
+ * Checks whether the encoding selected for PostgreSQL and the
+ * encoding used by the system locale match.
+ */
+
+struct encoding_match
+{
+ enum pg_enc pg_enc_code;
+ char *system_enc_name;
+};
+
+struct encoding_match encoding_match_list[] = {
+ { PG_EUC_JP, "EUC-JP" },
+ { PG_EUC_JP, "eucJP" },
+ { PG_EUC_JP, "IBM-eucJP" },
+ { PG_EUC_JP, "sdeckanji" },
+
+ { PG_EUC_CN, "EUC-CN" },
+ { PG_EUC_CN, "eucCN" },
+ { PG_EUC_CN, "IBM-eucCN" },
+ { PG_EUC_CN, "GB2312" },
+ { PG_EUC_CN, "dechanzi" },
+
+ { PG_EUC_KR, "EUC-KR" },
+ { PG_EUC_KR, "eucKR" },
+ { PG_EUC_KR, "IBM-eucKR" },
+ { PG_EUC_KR, "deckorean" },
+ { PG_EUC_KR, "5601" },
+
+ { PG_EUC_TW, "EUC-TW" },
+ { PG_EUC_TW, "eucTW" },
+ { PG_EUC_TW, "IBM-eucTW" },
+ { PG_EUC_TW, "cns11643" },
+
+#ifdef NOT_VERIFIED
+ { PG_JOHAB, "???" },
+#endif
+
+ { PG_UTF8, "UTF-8" },
+ { PG_UTF8, "utf8" },
+
+ { PG_LATIN1, "ISO-8859-1" },
+ { PG_LATIN1, "ISO8859-1" },
+ { PG_LATIN1, "iso88591" },
+
+ { PG_LATIN2, "ISO-8859-2" },
+ { PG_LATIN2, "ISO8859-2" },
+ { PG_LATIN2, "iso88592" },
+
+ { PG_LATIN3, "ISO-8859-3" },
+ { PG_LATIN3, "ISO8859-3" },
+ { PG_LATIN3, "iso88593" },
+
+ { PG_LATIN4, "ISO-8859-4" },
+ { PG_LATIN4, "ISO8859-4" },
+ { PG_LATIN4, "iso88594" },
+
+ { PG_LATIN5, "ISO-8859-9" },
+ { PG_LATIN5, "ISO8859-9" },
+ { PG_LATIN5, "iso88599" },
+
+ { PG_LATIN6, "ISO-8859-10" },
+ { PG_LATIN6, "ISO8859-10" },
+ { PG_LATIN6, "iso885910" },
+
+ { PG_LATIN7, "ISO-8859-13" },
+ { PG_LATIN7, "ISO8859-13" },
+ { PG_LATIN7, "iso885913" },
+
+ { PG_LATIN8, "ISO-8859-14" },
+ { PG_LATIN8, "ISO8859-14" },
+ { PG_LATIN8, "iso885914" },
+
+ { PG_LATIN9, "ISO-8859-15" },
+ { PG_LATIN9, "ISO8859-15" },
+ { PG_LATIN9, "iso885915" },
+
+ { PG_LATIN10, "ISO-8859-16" },
+ { PG_LATIN10, "ISO8859-16" },
+ { PG_LATIN10, "iso885916" },
+
+ { PG_WIN1256, "CP1256" },
+ { PG_TCVN, "CP1258" },
+#ifdef NOT_VERIFIED
+ { PG_WIN874, "???" },
+#endif
+ { PG_KOI8R, "KOI8-R" },
+ { PG_WIN1251, "CP1251" },
+ { PG_ALT, "CP866" },
+
+ { PG_ISO_8859_5, "ISO-8859-5" },
+ { PG_ISO_8859_5, "ISO8859-5" },
+ { PG_ISO_8859_5, "iso88595" },
+
+ { PG_ISO_8859_6, "ISO-8859-6" },
+ { PG_ISO_8859_6, "ISO8859-6" },
+ { PG_ISO_8859_6, "iso88596" },
+
+ { PG_ISO_8859_7, "ISO-8859-7" },
+ { PG_ISO_8859_7, "ISO8859-7" },
+ { PG_ISO_8859_7, "iso88597" },
+
+ { PG_ISO_8859_8, "ISO-8859-8" },
+ { PG_ISO_8859_8, "ISO8859-8" },
+ { PG_ISO_8859_8, "iso88598" },
+
+ { PG_SQL_ASCII, NULL } /* end marker */
+};
+
+static char *
+get_encoding_from_locale(const char *ctype)
+{
+ char *save;
+ char *sys;
+
+ save = setlocale(LC_CTYPE, NULL);
+ if (!save)
+ return NULL;
+ save = xstrdup(save);
+
+ setlocale(LC_CTYPE, ctype);
+ sys = nl_langinfo(CODESET);
+ sys = xstrdup(sys);
+
+ setlocale(LC_CTYPE, save);
+ free(save);
+
+ return sys;
+}
+
+static void
+check_encodings_match(int pg_enc, const char *ctype)
+{
+ char *sys;
+ int i;
+
+ sys = get_encoding_from_locale(ctype);
+
+ for (i = 0; encoding_match_list[i].system_enc_name; i++)
+ {
+ if (pg_enc == encoding_match_list[i].pg_enc_code
+ && strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
+ {
+ free(sys);
+ return;
+ }
+ }
+
+ fprintf(stderr,
+ _("%s: warning: encoding mismatch\n"), progname);
+ fprintf(stderr,
+ _("The encoding you selected (%s) and the encoding that the selected\n"
+ "locale uses (%s) are not known to match. This may lead to\n"
+ "misbehavior in various character string processing functions. To fix\n"
+ "this situation, rerun %s and either do not specify an encoding\n"
+ "explicitly, or choose a matching combination.\n"),
+ pg_encoding_to_char(pg_enc), sys, progname);
+
+ free(sys);
+ return;
+}
+
+static int
+find_matching_encoding(const char *ctype)
+{
+ char *sys;
+ int i;
+
+ sys = get_encoding_from_locale(ctype);
+
+ for (i = 0; encoding_match_list[i].system_enc_name; i++)
+ {
+ if (strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
+ {
+ free(sys);
+ return encoding_match_list[i].pg_enc_code;
+ }
+ }
+
+ free(sys);
+ return -1;
+}
+#endif /* HAVE_LANGINFO_H */
+
/*
* get short version of VERSION
*/
* make the data directory (or one of its subdirectories if subdir is not NULL)
*/
static bool
-mkdatadir(char *subdir)
+mkdatadir(const char *subdir)
{
char *path;
- int res;
path = xmalloc(strlen(pg_data) + 2 +
(subdir == NULL ? 0 : strlen(subdir)));
else
strcpy(path, pg_data);
- res = mkdir(path, 0700);
- if (res == 0)
- return true;
- else if (subdir == NULL || errno != ENOENT)
- return false;
- else
- return !mkdir_p(path, 0700);
+ return (mkdir_p(path, 0700) == 0);
}
static void
set_input(char **dest, char *filename)
{
- *dest = xmalloc(strlen(datadir) + strlen(filename) + 2);
- sprintf(*dest, "%s/%s", datadir, filename);
+ *dest = xmalloc(strlen(share_path) + strlen(filename) + 2);
+ sprintf(*dest, "%s/%s", share_path, filename);
}
/*
if (stat(path, &statbuf) != 0 || !S_ISREG(statbuf.st_mode))
{
fprintf(stderr,
- "%s: file \"%s\" not found\n"
- "This means you have a corrupted installation or identified\n"
- "the wrong directory with the invocation option -L.\n",
+ _("%s: file \"%s\" does not exist\n"
+ "This means you have a corrupted installation or identified\n"
+ "the wrong directory with the invocation option -L.\n"),
progname, path);
exit(1);
}
}
-/*
- * TODO - clean this up and handle the errors properly
- * don't overkill
- */
-#define FIND_SUCCESS 0
-#define FIND_NOT_FOUND 1
-#define FIND_STAT_ERR 2
-#define FIND_NOT_REGFILE 3
-#define FIND_BAD_PERM 4
-#define FIND_EXEC_ERR 5
-#define FIND_WRONG_VERSION 6
-
-/*
- * see if there is a postgres executable in the given path, and giving the
- * right version number
- */
-static int
-find_postgres(char *path)
-{
- char fn[MAXPGPATH];
- char cmd[MAXPGPATH];
- char line[100];
-
-#ifndef WIN32
- int permmask = S_IROTH | S_IXOTH;
-#endif
-
- struct stat statbuf;
- FILE *pgver;
- int plen = strlen(path);
-
- if (plen > 0 && path[plen - 1] != '/')
- snprintf(fn, sizeof(fn), "%s/postgres%s", path, EXE);
- else
- snprintf(fn, sizeof(fn), "%spostgres%s", path, EXE);
-
- if (stat(fn, &statbuf) != 0)
- {
- if (errno == ENOENT)
- return FIND_NOT_FOUND;
- else
- return FIND_STAT_ERR;
- }
- if (!S_ISREG(statbuf.st_mode))
- return FIND_NOT_REGFILE;
-
-#ifndef WIN32
-
- /*
- * Only unix requires this test, on WIN32 an .exe file should be
- * executable
- */
- if ((statbuf.st_mode & permmask) != permmask)
- return FIND_BAD_PERM;
-#endif
-
- snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -V 2>%s", path, DEVNULL);
-
- if ((pgver = popen(cmd, "r")) == NULL)
- return FIND_EXEC_ERR;
-
- if (fgets(line, sizeof(line), pgver) == NULL)
- perror("fgets failure");
-
- pclose(pgver);
-
- if (strcmp(line, PG_VERSIONSTR) != 0)
- return FIND_WRONG_VERSION;
-
- return FIND_SUCCESS;
-}
-
-/*
- * Windows doesn't like relative paths to executables (other things work fine)
- * so we call its builtin function to expand them. Elsewhere this is a NOOP
- */
-#ifdef WIN32
-static char *
-expanded_path(char *path)
-{
- char abspath[MAXPGPATH];
-
- if (_fullpath(abspath, path, sizeof(abspath)) == NULL)
- {
- perror("expanded path");
- return path;
- }
- canonicalize_path(abspath);
- return xstrdup(abspath);
-}
-#endif
-
-/*
- * set the paths pointing to postgres
- *
- * look for it in the same place we found this program, or in the environment
- * path, or in the configured bindir.
- * We do it in this order because during upgrades users might move
- * their trees to backup places, so the hard-wired bindir might be inaccurate.
- *
- * XXX this needs work, as its error handling is vastly inferior to the
- * shell-script version, in particular the case where a postgres executable
- * is failing
- */
-static int
-set_paths(void)
-{
- if (testpath && !self_path)
- {
- char *path,
- *cursor;
- int pathlen,
- i,
- pathsegs;
- char **pathbits;
- char buf[MAXPGPATH];
- struct stat statbuf;
-
- path = xstrdup(getenv("PATH"));
- pathlen = strlen(path);
-
- for (i = 0, pathsegs = 1; i < pathlen; i++)
- {
- if (path[i] == PATHSEP)
- pathsegs++;
- }
-
- pathbits = (char **) xmalloc(pathsegs * sizeof(char *));
- for (i = 0, pathsegs = 0, cursor = path; i <= pathlen; i++)
- {
- if (path[i] == PATHSEP || path[i] == 0)
- {
- path[i] = 0;
- if (strlen(cursor) == 0)
- {
- /* empty path segment means current directory */
- pathbits[pathsegs] = xstrdup(".");
- }
- else
- {
- canonicalize_path(cursor);
- pathbits[pathsegs] = cursor;
- }
- pathsegs++;
- cursor = path + i + 1;
- }
- }
-
- for (i = 0; i < pathsegs; i++)
- {
- snprintf(buf, sizeof(buf), "%s/%s%s", pathbits[i], progname, EXE);
- if (stat(buf, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
- {
- self_path = pathbits[i];
- break;
- }
- }
- }
-
- if (testpath && self_path &&
- (find_postgres(expanded_path(self_path)) == 0))
- {
- /* we found postgres on out own path */
- pgpath = expanded_path(self_path);
- }
- else
- {
- /* look in the hardcoded bindir */
- int res;
- char *cbindir;
-
- cbindir = xstrdup(bindir);
- canonicalize_path(cbindir);
- res = find_postgres(expanded_path(cbindir));
- if (res == 0)
- pgpath = expanded_path(cbindir);
- else
- return 1;
- }
-
- return 0;
-}
-
/*
* write out the PG_VERSION file in the data dir, or its subdirectory
* if extrapath is not NULL
sprintf(path, "%s/%s/PG_VERSION", pg_data, extrapath);
}
version_file = fopen(path, PG_BINARY_W);
+ if (version_file == NULL)
+ exit_nicely();
fprintf(version_file, "%s\n", short_version);
- fclose(version_file);
+ if (fclose(version_file))
+ exit_nicely();
}
/*
path = xmalloc(strlen(pg_data) + 17);
sprintf(path, "%s/postgresql.conf", pg_data);
conf_file = fopen(path, PG_BINARY_W);
- fclose(conf_file);
+ if (conf_file == NULL || fclose(conf_file))
+ exit_nicely();
}
/*
int i,
status;
- printf("selecting default max_connections ... ");
+ printf(_("selecting default max_connections ... "));
fflush(stdout);
for (i = 0; i < len; i++)
{
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x0 %s "
+ "%s\"%s\" -boot -x0 %s "
"-c shared_buffers=%d -c max_connections=%d template1 "
- "<%s >%s 2>&1",
- pgpath, boot_options,
+ "< \"%s\" > \"%s\" 2>&1%s",
+ SYSTEMQUOTE, backend_exec, boot_options,
conns[i] * 5, conns[i],
- DEVNULL, DEVNULL);
+ DEVNULL, DEVNULL, SYSTEMQUOTE);
status = system(cmd);
if (status == 0)
break;
int i,
status;
- printf("selecting default shared_buffers ... ");
+ printf(_("selecting default shared_buffers ... "));
fflush(stdout);
for (i = 0; i < len; i++)
{
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x0 %s "
+ "%s\"%s\" -boot -x0 %s "
"-c shared_buffers=%d -c max_connections=%d template1 "
- "<%s >%s 2>&1",
- pgpath, boot_options,
+ "< \"%s\" > \"%s\" 2>&1%s",
+ SYSTEMQUOTE, backend_exec, boot_options,
bufs[i], n_connections,
- DEVNULL, DEVNULL);
+ DEVNULL, DEVNULL, SYSTEMQUOTE);
status = system(cmd);
if (status == 0)
break;
char repltok[100];
char path[MAXPGPATH];
- fputs("creating configuration files ... ", stdout);
+ fputs(_("creating configuration files ... "), stdout);
fflush(stdout);
/* postgresql.conf */
"host all all ::1",
"#host all all ::1");
#endif
-
+
+ /* Replace default authentication methods */
+ conflines = replace_token(conflines,
+ "@authmethod@",
+ authmethod);
+
+ conflines = replace_token(conflines,
+ "@authcomment@",
+ strcmp(authmethod,"trust") ? "" : authtrust_warning);
+
snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
writefile(path, conflines);
PG_CMD_DECL;
- printf("creating template1 database in %s/base/1 ... ", pg_data);
+ printf(_("creating template1 database in %s/base/1 ... "), pg_data);
fflush(stdout);
if (debug)
if (strcmp(headerline, *bki_lines) != 0)
{
fprintf(stderr,
- "%s: input file \"%s\" does not belong to PostgreSQL %s\n"
+ _("%s: input file \"%s\" does not belong to PostgreSQL %s\n"
"Check your installation or specify the correct path "
- "using the option -L.\n",
+ "using the option -L.\n"),
progname, bki_file, PG_VERSION);
exit_nicely();
snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
putenv(xstrdup(cmd));
- putenv("LC_ALL");
+ unsetenv("LC_ALL");
+
+ /* Also ensure backend isn't confused by this environment var: */
+ unsetenv("PGCLIENTENCODING");
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x1 %s %s template1",
- pgpath, boot_options, talkargs);
+ "\"%s\" -boot -x1 %s %s template1",
+ backend_exec, boot_options, talkargs);
PG_CMD_OPEN;
PG_CMD_DECL;
- fputs("initializing pg_shadow ... ", stdout);
+ fputs(_("initializing pg_shadow ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
char pwdpath[MAXPGPATH];
struct stat statbuf;
- pwd1 = simple_prompt("Enter new superuser password: ", 100, false);
- pwd2 = simple_prompt("Enter it again: ", 100, false);
- if (strcmp(pwd1, pwd2) != 0)
+ if (pwprompt)
{
- fprintf(stderr, "Passwords didn't match.\n");
- exit_nicely();
+ /*
+ * Read password from terminal
+ */
+ pwd1 = simple_prompt("Enter new superuser password: ", 100, false);
+ pwd2 = simple_prompt("Enter it again: ", 100, false);
+ if (strcmp(pwd1, pwd2) != 0)
+ {
+ fprintf(stderr, _("Passwords didn't match.\n"));
+ exit_nicely();
+ }
+ free(pwd2);
}
- free(pwd2);
+ else
+ {
+ /*
+ * Read password from file
+ *
+ * Ideally this should insist that the file not be world-readable.
+ * However, this option is mainly intended for use on Windows where
+ * file permissions may not exist at all, so we'll skip the paranoia
+ * for now.
+ */
+ FILE *pwf = fopen(pwfilename,"r");
+ char pwdbuf[MAXPGPATH];
+ int i;
- printf("setting password ... ");
+ if (!pwf)
+ {
+ fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
+ progname, pwfilename, strerror(errno));
+ exit_nicely();
+ }
+ if (!fgets(pwdbuf, sizeof(pwdbuf), pwf))
+ {
+ fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"),
+ progname, pwfilename, strerror(errno));
+ exit_nicely();
+ }
+ fclose(pwf);
+
+ i = strlen(pwdbuf);
+ while (i > 0 && (pwdbuf[i-1] == '\r' || pwdbuf[i-1] == '\n'))
+ pwdbuf[--i] = '\0';
+
+ pwd1 = xstrdup(pwdbuf);
+
+ }
+ printf(_("setting password ... "));
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
if (fprintf(pg,
- "ALTER USER \"%s\" WITH PASSWORD '%s';\n", username, pwd1) < 0)
+ "ALTER USER \"%s\" WITH PASSWORD '%s';\n", effective_user, pwd1) < 0)
{
/* write failure */
exit_nicely();
if (stat(pwdpath, &statbuf) != 0 || !S_ISREG(statbuf.st_mode))
{
fprintf(stderr,
- "%s: The password file was not generated. "
- "Please report this problem.\n",
+ _("%s: The password file was not generated. "
+ "Please report this problem.\n"),
progname);
exit_nicely();
}
PG_CMD_DECL;
- fputs("enabling unlimited row size for system tables ... ", stdout);
+ fputs(_("enabling unlimited row size for system tables ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
PG_CMD_DECL;
- fputs("initializing pg_depend ... ", stdout);
+ fputs(_("initializing pg_depend ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
char **sysviews_setup;
- fputs("creating system views ... ", stdout);
+ fputs(_("creating system views ... "), stdout);
fflush(stdout);
sysviews_setup = readfile(system_views_file);
* We use -N here to avoid backslashing stuff in system_views.sql
*/
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s -N template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s -N template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
PG_CMD_DECL_NOLINE;
int fres;
- fputs("loading pg_description ... ", stdout);
+ fputs(_("loading pg_description ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
char **conv_lines;
- fputs("creating conversions ... ", stdout);
+ fputs(_("creating conversions ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
char **priv_lines;
- fputs("setting privileges on built-in objects ... ", stdout);
+ fputs(_("setting privileges on built-in objects ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
priv_lines = replace_token(privileges_setup,
- "$POSTGRES_SUPERUSERNAME", username);
+ "$POSTGRES_SUPERUSERNAME", effective_user);
for (line = priv_lines; *line != NULL; line++)
PG_CMD_PUTLINE;
char **lines;
int fres;
- fputs("creating information schema ... ", stdout);
+ fputs(_("creating information schema ... "), stdout);
fflush(stdout);
lines = readfile(info_schema_file);
* We use -N here to avoid backslashing stuff in information_schema.sql
*/
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s -N template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s -N template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
PG_CMD_CLOSE;
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
{
PG_CMD_DECL_NOLINE;
- fputs("vacuuming database template1 ... ", stdout);
+ fputs(_("vacuuming database template1 ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
PG_CMD_DECL;
- fputs("copying template1 to template0 ... ", stdout);
+ fputs(_("copying template1 to template0 ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
DEVNULL);
PG_CMD_OPEN;
{
/* handle systems that reset the handler, like Windows (grr) */
pqsignal(signum, trapsig);
- not_ok = true;
+ caught_signal = true;
}
/*
static void
check_ok()
{
- if (not_ok)
+ if (caught_signal)
{
- printf("Caught Signal.\n");
+ printf(_("caught signal\n"));
+ exit_nicely();
+ }
+ else if (output_failed)
+ {
+ printf(_("could not write to child process\n"));
exit_nicely();
}
else
{
- /* no signal caught */
- printf("ok\n");
+ /* all seems well */
+ printf(_("ok\n"));
}
}
/* should we exit here? */
if (!ret)
- fprintf(stderr, "%s: invalid locale name \"%s\"\n", progname, locale);
+ fprintf(stderr, _("%s: invalid locale name \"%s\"\n"), progname, locale);
return ret;
}
}
-/*
- * help text data
- *
- * Note: $CMDNAME is replaced by the right thing in usage()
- */
-char *usage_text[] = {
- "$CMDNAME initializes a PostgreSQL database cluster.\n",
- "\n",
- "Usage:\n",
- " $CMDNAME [OPTION]... [DATADIR]\n",
- "\n",
- "Options:\n",
- " [-D, --pgdata=]DATADIR location for this database cluster\n",
- " -E, --encoding=ENCODING set default encoding for new databases\n",
- " --locale=LOCALE initialize database cluster with given locale\n",
- " --lc-collate, --lc-ctype, --lc-messages=LOCALE\n",
- " --lc-monetary, --lc-numeric, --lc-time=LOCALE\n",
- " initialize database cluster with given locale\n",
- " in the respective category (default taken from\n",
- " environment)\n",
- " --no-locale equivalent to --locale=C\n",
- " -U, --username=NAME database superuser name\n",
- " -W, --pwprompt prompt for a password for the new superuser\n",
- " -?, --help show this help, then exit\n",
- " -V, --version output version information, then exit\n",
- "\n",
- "Less commonly used options: \n",
- " -d, --debug generate lots of debugging output\n",
- " -s, --show show internal settings\n",
- " -L DIRECTORY where to find the input files\n",
- " -n, --noclean do not clean up after errors\n",
- "\n",
- "If the data directory is not specified, the environment variable PGDATA\n",
- "is used.\n",
- "\n",
- "Report bugs to <pgsql-bugs@postgresql.org>.\n",
- NULL
-};
-
-
/*
* print help text
*/
static void
-usage(void)
+usage(const char *progname)
{
- int i;
- char **newtext;
-
- newtext = replace_token(usage_text, "$CMDNAME", progname);
-
- for (i = 0; newtext[i]; i++)
- fputs(newtext[i], stdout); /* faster than printf */
+ printf(_("%s initializes a PostgreSQL database cluster.\n\n"), progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTION]... [DATADIR]\n"), progname);
+ printf(_("\nOptions:\n"));
+ printf(_(" [-D, --pgdata=]DATADIR location for this database cluster\n"));
+ printf(_(" -E, --encoding=ENCODING set default encoding for new databases\n"));
+ printf(_(" --locale=LOCALE initialize database cluster with given locale\n"));
+ printf(_(" --lc-collate, --lc-ctype, --lc-messages=LOCALE\n"
+ " --lc-monetary, --lc-numeric, --lc-time=LOCALE\n"
+ " initialize database cluster with given locale\n"
+ " in the respective category (default taken from\n"
+ " environment)\n"));
+ printf(_(" --no-locale equivalent to --locale=C\n"));
+ printf(_(" -A, --auth=method default authentication method for local connections\n"));
+ printf(_(" -U, --username=NAME database superuser name\n"));
+ printf(_(" -W, --pwprompt prompt for a password for the new superuser\n"));
+ printf(_(" --pwfile=filename read password for the new superuser from file\n"));
+ printf(_(" -?, --help show this help, then exit\n"));
+ printf(_(" -V, --version output version information, then exit\n"));
+ printf(_("\nLess commonly used options:\n"));
+ printf(_(" -d, --debug generate lots of debugging output\n"));
+ printf(_(" -s, --show show internal settings\n"));
+ printf(_(" -L DIRECTORY where to find the input files\n"));
+ printf(_(" -n, --noclean do not clean up after errors\n"));
+ printf(_("\nIf the data directory is not specified, the environment variable PGDATA\n"
+ "is used.\n"));
+ printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
}
-
int
main(int argc, char *argv[])
{
{"lc-time", required_argument, NULL, 6},
{"lc-messages", required_argument, NULL, 7},
{"no-locale", no_argument, NULL, 8},
+ {"auth", required_argument, NULL, 'A'},
{"pwprompt", no_argument, NULL, 'W'},
+ {"pwfile", required_argument, NULL, 9},
{"username", required_argument, NULL, 'U'},
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'},
};
int c,
- i;
+ i,
+ ret;
int option_index;
char *short_version;
char *pgdenv; /* PGDATA value got from sent to
* environment */
- char *subdirs[] =
- {"global", "pg_xlog", "pg_clog", "base", "base/1"};
- char *lastsep;
- char *carg0;
-#if defined(__CYGWIN__) || defined(WIN32)
- char *exe; /* location of exe suffix in progname */
-#endif
-
- setlocale(LC_ALL, "");
-
- /* parse argv[0] - detect explicit path if there was one */
- carg0 = xstrdup(argv[0]);
- canonicalize_path(carg0);
-
- lastsep = strrchr(carg0, '/');
- progname = lastsep ? xstrdup(lastsep + 1) : carg0;
-
-#if defined(__CYGWIN__) || defined(WIN32)
- if (strlen(progname) > 4 &&
- (exe = progname + (strlen(progname) - 4)) &&
- stricmp(exe, EXE) == 0)
- {
- /* strip .exe suffix, regardless of case */
- *exe = '\0';
- }
-#endif
+ static const char *subdirs[] = {
+ "global",
+ "pg_xlog",
+ "pg_xlog/archive_status",
+ "pg_clog",
+ "pg_subtrans",
+ "base",
+ "base/1",
+ "pg_tblspc"
+ };
- if (lastsep)
- {
- self_path = carg0;
- *lastsep = '\0';
- }
- else
- {
- /* no path known to ourselves from argv[0] */
- self_path = NULL;
- }
+ progname = get_progname(argv[0]);
+ set_pglocale_pgservice(argv[0], "initdb");
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ usage(progname);
+ exit(0);
+ }
+ if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
+ {
+ puts("initdb (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
/* process command-line options */
- while (1)
+ while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:", long_options, &option_index)) != -1)
{
- /*
- * a : as the first option char here lets us use ? as a short
- * option
- */
- c = getopt_long(argc, argv, ":D:E:WU:?sVdnL:",
- long_options, &option_index);
-
- if (c == -1)
- break;
-
switch (c)
{
+ case 'A':
+ authmethod = xstrdup(optarg);
+ break;
case 'D':
pg_data = xstrdup(optarg);
break;
break;
case 'd':
debug = true;
- printf("Running in debug mode.\n");
+ printf(_("Running in debug mode.\n"));
break;
case 'n':
noclean = true;
- printf("Running in noclean mode. Mistakes will not be cleaned up.\n");
+ printf(_("Running in noclean mode. Mistakes will not be cleaned up.\n"));
break;
case 'L':
- datadir = xstrdup(optarg);
+ share_path = xstrdup(optarg);
break;
case 1:
locale = xstrdup(optarg);
case 8:
locale = "C";
break;
- case '?':
- show_help = true;
+ case 9:
+ pwfilename = xstrdup(optarg);
break;
case 's':
show_setting = true;
break;
- case 'V':
- show_version = true;
- break;
default:
- show_help = true;
- printf("Unrecognized option: %c\n", c);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ progname);
+ exit(1);
}
-
}
/* Non-option argument specifies data directory */
}
if (optind < argc)
- show_help = true;
+ {
+ fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
+ progname, argv[optind + 1]);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ progname);
+ }
- if (show_version)
+ if (pwprompt && pwfilename)
{
- /* hard coded name here, in case they rename executable */
- printf("initdb (PostgreSQL) %s\n", PG_VERSION);
- exit(0);
+ fprintf(stderr, _("%s: you cannot specify both password prompt and password file\n"), progname);
+ exit(1);
+ }
+
+ if (authmethod == NULL || !strlen(authmethod))
+ {
+ authwarning = _("\nWARNING: enabling \"trust\" authentication for local connections.\n"
+ "You can change this by editing pg_hba.conf or using the -A flag the\n"
+ "next time you run initdb.\n");
+ authmethod="trust";
+ }
+
+ if (strcmp(authmethod,"md5") &&
+ strcmp(authmethod,"ident") &&
+ strncmp(authmethod,"ident ",6) && /* ident with space = param */
+ strcmp(authmethod,"trust") &&
+#ifdef USE_PAM
+ strcmp(authmethod,"pam") &&
+ strncmp(authmethod,"pam ",4) && /* pam with space = param */
+#endif
+ strcmp(authmethod,"crypt") &&
+ strcmp(authmethod,"password")
+ )
+ /*
+ * Kerberos methods not listed because they are not supported
+ * over local connections and are rejected in hba.c
+ */
+ {
+ fprintf(stderr, _("%s: unknown authentication method \"%s\".\n"), progname, authmethod);
+ exit(1);
}
- if (show_help)
+ if ((!strcmp(authmethod,"md5") ||
+ !strcmp(authmethod,"crypt") ||
+ !strcmp(authmethod,"password")) &&
+ !(pwprompt || pwfilename))
{
- usage();
- exit(0);
+ fprintf(stderr, _("%s: you need to specify a password for the superuser to enable %s authentication.\n"), progname, authmethod);
+ exit(1);
}
if (strlen(pg_data) == 0)
else
{
fprintf(stderr,
- "%s: no data directory specified\n"
- "You must identify the directory where the data "
- "for this database system\n"
- "will reside. Do this with either the invocation "
- "option -D or the\n"
- "environment variable PGDATA.\n",
+ _("%s: no data directory specified\n"
+ "You must identify the directory where the data for this database system\n"
+ "will reside. Do this with either the invocation option -D or the\n"
+ "environment variable PGDATA.\n"),
progname);
exit(1);
}
sprintf(pgdenv, "PGDATA=%s", pg_data);
putenv(pgdenv);
- if (set_paths() != 0)
+ if ((ret = find_other_exec(argv[0], "postgres", PG_VERSIONSTR,
+ backend_exec)) < 0)
{
- fprintf(stderr,
- "The program \"postgres\" is needed by %s "
- "but was not found in \n"
- "the directory \"%s\". Check your installation.\n",
- progname, bindir);
+ if (ret == -1)
+ fprintf(stderr,
+ _("The program \"postgres\" is needed by %s "
+ "but was not found in the same directory as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
+ else
+ fprintf(stderr,
+ _("The program \"postgres\" was found by %s "
+ "but was not the same version as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
exit(1);
}
+ /* store binary directory */
+ strcpy(bin_path, backend_exec);
+ *last_dir_separator(bin_path) = '\0';
+
+ if (!share_path)
+ {
+ share_path = xmalloc(MAXPGPATH);
+ get_share_path(backend_exec, share_path);
+ }
+
+ canonicalize_path(share_path);
+
if ((short_version = get_short_version()) == NULL)
{
- fprintf(stderr, "%s: could not get valid short version\n", progname);
+ fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
exit(1);
}
- effective_user = get_id();
- if (!strlen(username))
- username = effective_user;
+ if (strlen(username))
+ effective_user = username;
+ else
+ effective_user = get_id();
if (strlen(encoding))
encodingid = get_encoding_id(encoding);
{
fprintf(stderr,
"VERSION=%s\n"
- "PGDATA=%s\ndatadir=%s\nPGPATH=%s\n"
- "ENCODING=%s\nENCODINGID=%s\n"
+ "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
"POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
PG_VERSION,
- pg_data, datadir, pgpath,
- encoding, encodingid,
- username, bki_file,
+ pg_data, share_path, bin_path,
+ effective_user, bki_file,
desc_file, conf_file,
hba_file, ident_file);
if (show_setting)
check_input(features_file);
check_input(system_views_file);
- printf("The files belonging to this database system will be owned "
+ setlocales();
+
+ printf(_("The files belonging to this database system will be owned "
"by user \"%s\".\n"
- "This user must also own the server process.\n\n",
+ "This user must also own the server process.\n\n"),
effective_user);
- setlocales();
-
if (strcmp(lc_ctype, lc_collate) == 0 &&
strcmp(lc_ctype, lc_time) == 0 &&
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0)
{
- printf("The database cluster will be initialized with locale %s.\n\n",
- lc_ctype);
+ printf(_("The database cluster will be initialized with locale %s.\n"), lc_ctype);
}
else
{
- printf("The database cluster will be initialized with locales\n"
+ printf(_("The database cluster will be initialized with locales\n"
" COLLATE: %s\n"
" CTYPE: %s\n"
" MESSAGES: %s\n"
" MONETARY: %s\n"
" NUMERIC: %s\n"
- " TIME: %s\n\n",
+ " TIME: %s\n"),
lc_collate,
lc_ctype,
lc_messages,
lc_time);
}
+#ifdef HAVE_LANGINFO_H
+ if (strcmp(lc_ctype, "C") != 0 && strcmp(lc_ctype, "POSIX") != 0)
+ {
+ if (strlen(encoding) == 0)
+ {
+ int tmp;
+ tmp = find_matching_encoding(lc_ctype);
+ if (tmp == -1)
+ {
+ fprintf(stderr, _("%s: could not find suitable encoding for locale \"%s\"\n"), progname, lc_ctype);
+ fprintf(stderr, _("Rerun %s with the -E option.\n"), progname);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
+ }
+ else
+ {
+ encodingid = encodingid_to_string(tmp);
+ printf(_("The default database encoding has accordingly been set to %s.\n"),
+ pg_encoding_to_char(tmp));
+ }
+ }
+ else
+ check_encodings_match(atoi(encodingid), lc_ctype);
+ }
+#endif /* HAVE_LANGINFO_H */
+
+ printf("\n");
+
umask(077);
/*
pqsignal(SIGTERM, trapsig);
#endif
+ /* Ignore SIGPIPE when writing to backend, so we can clean up */
+#ifdef SIGPIPE
+ pqsignal(SIGPIPE, SIG_IGN);
+#endif
+
switch (check_data_dir())
{
case 0:
/* PGDATA not there, must create it */
- printf("creating directory %s ... ",
+ printf(_("creating directory %s ... "),
pg_data);
fflush(stdout);
case 1:
/* Present but empty, fix permissions and use it */
- printf("fixing permissions on existing directory %s ... ",
+ printf(_("fixing permissions on existing directory %s ... "),
pg_data);
fflush(stdout);
if (chmod(pg_data, 0700) != 0)
{
perror(pg_data);
- /* don't exit_nicely(), it'll try to remove pg_data contents */
- exit(1);
+ exit_nicely();
}
else
check_ok();
+
+ found_existing_pgdata = true;
break;
case 2:
/* Present and not empty */
fprintf(stderr,
- "%s: directory \"%s\" exists but is not empty\n"
+ _("%s: directory \"%s\" exists but is not empty\n"
"If you want to create a new database system, either remove or empty\n"
"the directory \"%s\" or run %s\n"
- "with an argument other than \"%s\".\n",
+ "with an argument other than \"%s\".\n"),
progname, pg_data, pg_data, progname, pg_data);
- /* don't exit_nicely(), it'll try to remove pg_data contents */
- exit(1);
+ exit(1); /* no further message needed */
default:
/* Trouble accessing directory */
perror(pg_data);
- /* don't exit_nicely(), it'll try to remove pg_data contents */
- exit(1);
+ exit_nicely();
}
/* Create required subdirectories */
for (i = 0; i < (sizeof(subdirs) / sizeof(char *)); i++)
{
- printf("creating directory %s/%s ... ", pg_data, subdirs[i]);
+ printf(_("creating directory %s/%s ... "), pg_data, subdirs[i]);
fflush(stdout);
if (!mkdatadir(subdirs[i]))
/* Bootstrap template1 */
bootstrap_template1(short_version);
- /* Make the per-database PGVERSION for template1 only after init'ing it */
+ /* Make the per-database PG_VERSION for template1 only after init'ing it */
set_short_version(short_version, "base/1");
/* Create the stuff we don't need to use bootstrap mode for */
setup_shadow();
- if (pwprompt)
+ if (pwprompt || pwfilename)
get_set_pwd();
unlimit_systables();
make_template0();
- printf("\nSuccess. You can now start the database server using:\n\n"
+ if (authwarning != NULL)
+ fprintf(stderr, authwarning);
+
+ printf(_("\nSuccess. You can now start the database server using:\n\n"
" %s%s%s/postmaster -D %s%s%s\n"
"or\n"
- " %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n",
- QUOTE_PATH, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
- QUOTE_PATH, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
+ " %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
+ QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
+ QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
return 0;
}