Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Functions | Variables

initdb.c File Reference

#include "postgres_fe.h"
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <locale.h>
#include <signal.h>
#include <time.h>
#include "mb/pg_wchar.h"
#include "getaddrinfo.h"
#include "getopt_long.h"
#include "miscadmin.h"
Include dependency graph for initdb.c:

Go to the source code of this file.

Data Structures

struct  tsearch_config_match

Defines

#define AUTHTRUST_WARNING
#define PG_CMD_DECL   char cmd[MAXPGPATH]; FILE *cmdfd
#define PG_CMD_OPEN
#define PG_CMD_CLOSE
#define PG_CMD_PUTS(line)
#define PG_CMD_PRINTF1(fmt, arg1)
#define PG_CMD_PRINTF2(fmt, arg1, arg2)
#define PG_CMD_PRINTF3(fmt, arg1, arg2, arg3)
#define QUOTE_PATH   ""
#define DIR_SEP   "/"
#define MIN_BUFS_FOR_CONNS(nconns)   ((nconns) * 10)

Functions

const char * select_default_timezone (const char *share_path)
static char ** replace_token (char **lines, const char *token, const char *replacement)
static char ** filter_lines_with_token (char **lines, const char *token)
static char ** readfile (const char *path)
static void writefile (char *path, char **lines)
static void walkdir (char *path, void(*action)(char *fname, bool isdir))
static void pre_sync_fname (char *fname, bool isdir)
static void fsync_fname (char *fname, bool isdir)
static FILE * popen_check (const char *command, const char *mode)
static void exit_nicely (void)
static char * get_id (void)
static char * get_encoding_id (char *encoding_name)
static bool mkdatadir (const char *subdir)
static void set_input (char **dest, char *filename)
static void check_input (char *path)
static void write_version_file (char *extrapath)
static void set_null_conf (void)
static void test_config_settings (void)
static void setup_config (void)
static void bootstrap_template1 (void)
static void setup_auth (void)
static void get_set_pwd (void)
static void setup_depend (void)
static void setup_sysviews (void)
static void setup_description (void)
static void setup_collation (void)
static void setup_conversion (void)
static void setup_dictionary (void)
static void setup_privileges (void)
static void set_info_version (void)
static void setup_schema (void)
static void load_plpgsql (void)
static void vacuum_db (void)
static void make_template0 (void)
static void make_postgres (void)
static void perform_fsync (void)
static void trapsig (int signum)
static void check_ok (void)
static char * escape_quotes (const char *src)
static int locale_date_order (const char *locale)
static bool check_locale_name (int category, const char *locale, char **canonname)
static bool check_locale_encoding (const char *locale, int encoding)
static void setlocales (void)
static void usage (const char *progname)
void get_restricted_token (void)
void setup_pgdata (void)
void setup_bin_paths (const char *argv0)
void setup_data_file_paths (void)
void setup_locale_encoding (void)
void setup_signals (void)
void setup_text_search (void)
void create_data_directory (void)
void create_xlog_symlink (void)
void warn_on_mount_point (int error)
void initialize_data_directory (void)
static char * encodingid_to_string (int enc)
static const char * find_matching_ts_config (const char *lc_type)
static size_t my_strftime (char *s, size_t max, const char *fmt, const struct tm *tm)
static void check_authmethod_unspecified (const char **authmethod)
static void check_authmethod_valid (const char *authmethod, const char **valid_methods, const char *conntype)
static void check_need_password (const char *authmethodlocal, const char *authmethodhost)
int main (int argc, char *argv[])

Variables

static const char * auth_methods_host []
static const char * auth_methods_local []
static char * share_path = NULL
static char * pg_data = ""
static char * encoding = ""
static char * locale = ""
static char * lc_collate = ""
static char * lc_ctype = ""
static char * lc_monetary = ""
static char * lc_numeric = ""
static char * lc_time = ""
static char * lc_messages = ""
static const char * default_text_search_config = ""
static char * username = ""
static bool pwprompt = false
static char * pwfilename = NULL
static const char * authmethodhost = ""
static const char * authmethodlocal = ""
static bool debug = false
static bool noclean = false
static bool do_sync = true
static bool sync_only = false
static bool show_setting = false
static bool data_checksums = false
static char * xlog_dir = ""
static const char * progname
static char * encodingid = "0"
static char * bki_file
static char * desc_file
static char * shdesc_file
static char * hba_file
static char * ident_file
static char * conf_file
static char * conversion_file
static char * dictionary_file
static char * info_schema_file
static char * features_file
static char * system_views_file
static bool made_new_pgdata = false
static bool found_existing_pgdata = false
static bool made_new_xlogdir = false
static bool found_existing_xlogdir = false
static char infoversion [100]
static bool caught_signal = false
static bool output_failed = false
static int output_errno = 0
static char * pgdata_native
static int n_connections = 10
static int n_buffers = 50
static char * authwarning = NULL
static const char * boot_options = "-F"
static const char * backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true"
const char * subdirs []
static char bin_path [MAXPGPATH]
static char backend_exec [MAXPGPATH]
static struct tsearch_config_match tsearch_config_languages []

Define Documentation

#define AUTHTRUST_WARNING
Value:
"# CAUTION: Configuring the system for local \"trust\" authentication\n" \
"# allows any local user to connect as any PostgreSQL user, including\n" \
"# the database superuser.  If you do not trust all your local users,\n" \
"# use another authentication method.\n"

Definition at line 157 of file initdb.c.

Referenced by setup_config().

#define DIR_SEP   "/"

Definition at line 314 of file initdb.c.

Referenced by main().

#define MIN_BUFS_FOR_CONNS (   nconns  )     ((nconns) * 10)

Referenced by test_config_settings().

#define PG_CMD_CLOSE
Value:
do { \
    if (pclose_check(cmdfd)) \
        exit_nicely(); /* message already printed by pclose_check */ \
} while (0)

Definition at line 282 of file initdb.c.

#define PG_CMD_DECL   char cmd[MAXPGPATH]; FILE *cmdfd

Definition at line 273 of file initdb.c.

#define PG_CMD_OPEN
Value:
do { \
    cmdfd = popen_check(cmd, "w"); \
    if (cmdfd == NULL) \
        exit_nicely(); /* message already printed by popen_check */ \
} while (0)

Definition at line 275 of file initdb.c.

#define PG_CMD_PRINTF1 (   fmt,
  arg1 
)
Value:
do { \
    if (fprintf(cmdfd, fmt, arg1) < 0 || fflush(cmdfd) < 0) \
        output_failed = true, output_errno = errno; \
} while (0)

Definition at line 294 of file initdb.c.

Referenced by setup_collation(), setup_description(), and setup_schema().

#define PG_CMD_PRINTF2 (   fmt,
  arg1,
  arg2 
)
Value:
do { \
    if (fprintf(cmdfd, fmt, arg1, arg2) < 0 || fflush(cmdfd) < 0) \
        output_failed = true, output_errno = errno; \
} while (0)

Definition at line 300 of file initdb.c.

Referenced by get_set_pwd().

#define PG_CMD_PRINTF3 (   fmt,
  arg1,
  arg2,
  arg3 
)
Value:
do { \
    if (fprintf(cmdfd, fmt, arg1, arg2, arg3) < 0 || fflush(cmdfd) < 0) \
        output_failed = true, output_errno = errno; \
} while (0)

Definition at line 306 of file initdb.c.

Referenced by setup_collation().

#define PG_CMD_PUTS (   line  ) 
Value:
do { \
    if (fputs(line, cmdfd) < 0 || fflush(cmdfd) < 0) \
        output_failed = true, output_errno = errno; \
} while (0)

Definition at line 288 of file initdb.c.

Referenced by bootstrap_template1(), load_plpgsql(), make_postgres(), make_template0(), setup_auth(), setup_collation(), setup_conversion(), setup_depend(), setup_description(), setup_dictionary(), setup_privileges(), setup_schema(), setup_sysviews(), and vacuum_db().

#define QUOTE_PATH   ""

Definition at line 313 of file initdb.c.

Referenced by main().


Function Documentation

static void bootstrap_template1 ( void   )  [static]

Definition at line 1370 of file initdb.c.

References _, backend_exec, bki_file, boot_options, buf, check_ok(), data_checksums, debug, encodingid, escape_quotes(), exit_nicely, free, lc_collate, lc_ctype, NAMEDATALEN, PG_CMD_PUTS, pg_data, pg_strdup(), progname, putenv, readfile(), replace_token(), snprintf(), unsetenv, and username.

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char       *talkargs = "";
    char      **bki_lines;
    char        headerline[MAXPGPATH];
    char        buf[64];

    printf(_("creating template1 database in %s/base/1 ... "), pg_data);
    fflush(stdout);

    if (debug)
        talkargs = "-d 5";

    bki_lines = readfile(bki_file);

    /* Check that bki file appears to be of the right version */

    snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n",
             PG_MAJORVERSION);

    if (strcmp(headerline, *bki_lines) != 0)
    {
        fprintf(stderr,
                _("%s: input file \"%s\" does not belong to PostgreSQL %s\n"
                  "Check your installation or specify the correct path "
                  "using the option -L.\n"),
                progname, bki_file, PG_VERSION);
        exit_nicely();
    }

    /* Substitute for various symbols used in the BKI file */

    sprintf(buf, "%d", NAMEDATALEN);
    bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);

    sprintf(buf, "%d", (int) sizeof(Pointer));
    bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf);

    bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
                              (sizeof(Pointer) == 4) ? "i" : "d");

    bki_lines = replace_token(bki_lines, "FLOAT4PASSBYVAL",
                              FLOAT4PASSBYVAL ? "true" : "false");

    bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
                              FLOAT8PASSBYVAL ? "true" : "false");

    bki_lines = replace_token(bki_lines, "POSTGRES", escape_quotes(username));

    bki_lines = replace_token(bki_lines, "ENCODING", encodingid);

    bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate));

    bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype));

    /*
     * Pass correct LC_xxx environment to bootstrap.
     *
     * The shell script arranged to restore the LC settings afterwards, but
     * there doesn't seem to be any compelling reason to do that.
     */
    snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate);
    putenv(pg_strdup(cmd));

    snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
    putenv(pg_strdup(cmd));

    unsetenv("LC_ALL");

    /* Also ensure backend isn't confused by this environment var: */
    unsetenv("PGCLIENTENCODING");

    snprintf(cmd, sizeof(cmd),
             "\"%s\" --boot -x1 %s %s %s",
             backend_exec,
             data_checksums ? "-k" : "",
             boot_options, talkargs);

    PG_CMD_OPEN;

    for (line = bki_lines; *line != NULL; line++)
    {
        PG_CMD_PUTS(*line);
        free(*line);
    }

    PG_CMD_CLOSE;

    free(bki_lines);

    check_ok();
}

static void check_authmethod_unspecified ( const char **  authmethod  )  [static]

Definition at line 2769 of file initdb.c.

References _, authwarning, and NULL.

Referenced by main().

{
    if (*authmethod == NULL || strlen(*authmethod) == 0)
    {
        authwarning = _("\nWARNING: enabling \"trust\" authentication for local connections\n"
                        "You can change this by editing pg_hba.conf or using the option -A, or\n"
            "--auth-local and --auth-host, the next time you run initdb.\n");
        *authmethod = "trust";
    }
}

static void check_authmethod_valid ( const char *  authmethod,
const char **  valid_methods,
const char *  conntype 
) [static]

Definition at line 2781 of file initdb.c.

References _, and progname.

Referenced by main().

{
    const char **p;

    for (p = valid_methods; *p; p++)
    {
        if (strcmp(authmethod, *p) == 0)
            return;
        /* with space = param */
        if (strchr(authmethod, ' '))
            if (strncmp(authmethod, *p, (authmethod - strchr(authmethod, ' '))) == 0)
                return;
    }

    fprintf(stderr, _("%s: invalid authentication method \"%s\" for \"%s\" connections\n"),
            progname, authmethod, conntype);
    exit(1);
}

static void check_input ( char *  path  )  [static]

Definition at line 975 of file initdb.c.

References _, progname, and strerror().

Referenced by setup_data_file_paths().

{
    struct stat statbuf;

    if (stat(path, &statbuf) != 0)
    {
        if (errno == ENOENT)
        {
            fprintf(stderr,
                    _("%s: file \"%s\" does not exist\n"), progname, path);
            fprintf(stderr,
                    _("This might mean you have a corrupted installation or identified\n"
                    "the wrong directory with the invocation option -L.\n"));
        }
        else
        {
            fprintf(stderr,
                 _("%s: could not access file \"%s\": %s\n"), progname, path,
                    strerror(errno));
            fprintf(stderr,
                    _("This might mean you have a corrupted installation or identified\n"
                    "the wrong directory with the invocation option -L.\n"));
        }
        exit(1);
    }
    if (!S_ISREG(statbuf.st_mode))
    {
        fprintf(stderr,
                _("%s: file \"%s\" is not a regular file\n"), progname, path);
        fprintf(stderr,
        _("This might mean you have a corrupted installation or identified\n"
          "the wrong directory with the invocation option -L.\n"));
        exit(1);
    }
}

static bool check_locale_encoding ( const char *  locale,
int  encoding 
) [static]

Definition at line 2519 of file initdb.c.

References _, pg_encoding_to_char(), pg_get_encoding_from_locale(), PG_SQL_ASCII, PG_UTF8, and progname.

Referenced by setup_locale_encoding().

{
    int         locale_enc;

    locale_enc = pg_get_encoding_from_locale(locale, true);

    /* See notes in createdb() to understand these tests */
    if (!(locale_enc == user_enc ||
          locale_enc == PG_SQL_ASCII ||
          locale_enc == -1 ||
#ifdef WIN32
          user_enc == PG_UTF8 ||
#endif
          user_enc == PG_SQL_ASCII))
    {
        fprintf(stderr, _("%s: encoding mismatch\n"), progname);
        fprintf(stderr,
                _("The encoding you selected (%s) and the encoding that the\n"
              "selected locale uses (%s) do not match.  This would lead to\n"
            "misbehavior in various character string processing functions.\n"
               "Rerun %s and either do not specify an encoding explicitly,\n"
                  "or choose a matching combination.\n"),
                pg_encoding_to_char(user_enc),
                pg_encoding_to_char(locale_enc),
                progname);
        return false;
    }
    return true;
}

static bool check_locale_name ( int  category,
const char *  locale,
char **  canonname 
) [static]

Definition at line 2477 of file initdb.c.

References _, free, NULL, pg_strdup(), and progname.

Referenced by setlocales().

{
    char       *save;
    char       *res;

    if (canonname)
        *canonname = NULL;      /* in case of failure */

    save = setlocale(category, NULL);
    if (!save)
        return false;           /* won't happen, we hope */

    /* save may be pointing at a modifiable scratch variable, so copy it. */
    save = pg_strdup(save);

    /* set the locale with setlocale, to see if it accepts it. */
    res = setlocale(category, locale);

    /* save canonical name if requested. */
    if (res && canonname)
        *canonname = pg_strdup(res);

    /* restore old value. */
    if (!setlocale(category, save))
        fprintf(stderr, _("%s: failed to restore old locale \"%s\"\n"),
                progname, save);
    free(save);

    /* should we exit here? */
    if (res == NULL)
        fprintf(stderr, _("%s: invalid locale name \"%s\"\n"),
                progname, locale);

    return (res != NULL);
}

static void check_need_password ( const char *  authmethodlocal,
const char *  authmethodhost 
) [static]

Definition at line 2801 of file initdb.c.

References _, progname, pwfilename, and pwprompt.

Referenced by main().

{
    if ((strcmp(authmethodlocal, "md5") == 0 ||
         strcmp(authmethodlocal, "password") == 0) &&
        (strcmp(authmethodhost, "md5") == 0 ||
         strcmp(authmethodhost, "password") == 0) &&
        !(pwprompt || pwfilename))
    {
        fprintf(stderr, _("%s: must specify a password for the superuser to enable %s authentication\n"), progname,
                (strcmp(authmethodlocal, "md5") == 0 ||
                 strcmp(authmethodlocal, "password") == 0)
                ? authmethodlocal
                : authmethodhost);
        exit(1);
    }
}

static void check_ok ( void   )  [static]

Definition at line 2380 of file initdb.c.

References _, caught_signal, exit_nicely, output_errno, output_failed, and strerror().

{
    if (caught_signal)
    {
        printf(_("caught signal\n"));
        fflush(stdout);
        exit_nicely();
    }
    else if (output_failed)
    {
        printf(_("could not write to child process: %s\n"),
               strerror(output_errno));
        fflush(stdout);
        exit_nicely();
    }
    else
    {
        /* all seems well */
        printf(_("ok\n"));
        fflush(stdout);
    }
}

void create_data_directory ( void   ) 

Definition at line 3150 of file initdb.c.

References _, check_ok(), exit_nicely, found_existing_pgdata, made_new_pgdata, mkdatadir(), NULL, pg_check_dir(), pg_data, progname, strerror(), and warn_on_mount_point().

Referenced by initialize_data_directory().

{
    int ret;

    switch ((ret = pg_check_dir(pg_data)))
    {
        case 0:
            /* PGDATA not there, must create it */
            printf(_("creating directory %s ... "),
                   pg_data);
            fflush(stdout);

            if (!mkdatadir(NULL))
                exit_nicely();
            else
                check_ok();

            made_new_pgdata = true;
            break;

        case 1:
            /* Present but empty, fix permissions and use it */
            printf(_("fixing permissions on existing directory %s ... "),
                   pg_data);
            fflush(stdout);

            if (chmod(pg_data, S_IRWXU) != 0)
            {
                fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
                        progname, pg_data, strerror(errno));
                exit_nicely();
            }
            else
                check_ok();

            found_existing_pgdata = true;
            break;

        case 2:
        case 3:
        case 4:
            /* Present and not empty */
            fprintf(stderr,
                    _("%s: directory \"%s\" exists but is not empty\n"),
                    progname, pg_data);
            if (ret != 4)
                warn_on_mount_point(ret);
            else
                fprintf(stderr,
                        _("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"),
                        pg_data, progname, pg_data);
            exit(1);            /* no further message needed */

        default:
            /* Trouble accessing directory */
            fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
                    progname, pg_data, strerror(errno));
            exit_nicely();
    }
}

void create_xlog_symlink ( void   ) 

Definition at line 3215 of file initdb.c.

References _, canonicalize_path(), check_ok(), exit_nicely, found_existing_xlogdir, is_absolute_path, made_new_xlogdir, pg_check_dir(), pg_data, pg_malloc(), pg_mkdir_p(), progname, strerror(), warn_on_mount_point(), and xlog_dir.

Referenced by initialize_data_directory().

{
    /* Create transaction log symlink, if required */
    if (strcmp(xlog_dir, "") != 0)
    {
        char       *linkloc;
        int         ret;

        /* clean up xlog directory name, check it's absolute */
        canonicalize_path(xlog_dir);
        if (!is_absolute_path(xlog_dir))
        {
            fprintf(stderr, _("%s: transaction log directory location must be an absolute path\n"), progname);
            exit_nicely();
        }

        /* check if the specified xlog directory exists/is empty */
        switch ((ret = pg_check_dir(xlog_dir)))
        {
            case 0:
                /* xlog directory not there, must create it */
                printf(_("creating directory %s ... "),
                       xlog_dir);
                fflush(stdout);

                if (pg_mkdir_p(xlog_dir, S_IRWXU) != 0)
                {
                    fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
                            progname, xlog_dir, strerror(errno));
                    exit_nicely();
                }
                else
                    check_ok();

                made_new_xlogdir = true;
                break;

            case 1:
                /* Present but empty, fix permissions and use it */
                printf(_("fixing permissions on existing directory %s ... "),
                       xlog_dir);
                fflush(stdout);

                if (chmod(xlog_dir, S_IRWXU) != 0)
                {
                    fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
                            progname, xlog_dir, strerror(errno));
                    exit_nicely();
                }
                else
                    check_ok();

                found_existing_xlogdir = true;
                break;

            case 2:
            case 3:
            case 4:
                /* Present and not empty */
                fprintf(stderr,
                        _("%s: directory \"%s\" exists but is not empty\n"),
                        progname, xlog_dir);
                if (ret != 4)
                    warn_on_mount_point(ret);
                else
                    fprintf(stderr,
                     _("If you want to store the transaction log there, either\n"
                       "remove or empty the directory \"%s\".\n"),
                            xlog_dir);
                exit_nicely();

            default:
                /* Trouble accessing directory */
                fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
                        progname, xlog_dir, strerror(errno));
                exit_nicely();
        }

        /* form name of the place where the symlink must go */
        linkloc = (char *) pg_malloc(strlen(pg_data) + 8 + 1);
        sprintf(linkloc, "%s/pg_xlog", pg_data);

#ifdef HAVE_SYMLINK
        if (symlink(xlog_dir, linkloc) != 0)
        {
            fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
                    progname, linkloc, strerror(errno));
            exit_nicely();
        }
#else
        fprintf(stderr, _("%s: symlinks are not supported on this platform"));
        exit_nicely();
#endif
    }
}

static char* encodingid_to_string ( int  enc  )  [static]

Definition at line 816 of file initdb.c.

References pg_strdup().

Referenced by get_encoding_id(), and setup_locale_encoding().

{
    char        result[20];

    sprintf(result, "%d", enc);
    return pg_strdup(result);
}

static char * escape_quotes ( const char *  src  )  [static]

Definition at line 321 of file initdb.c.

References _, escape_single_quotes_ascii(), and progname.

Referenced by bootstrap_template1(), get_set_pwd(), setup_collation(), setup_config(), setup_description(), setup_privileges(), and setup_schema().

{
    char *result = escape_single_quotes_ascii(src);
    if (!result)
    {
        fprintf(stderr, _("%s: out of memory\n"), progname);
        exit(1);
    }
    return result;
}

static void exit_nicely ( void   )  [static]

Definition at line 705 of file initdb.c.

References _, found_existing_pgdata, found_existing_xlogdir, made_new_pgdata, made_new_xlogdir, noclean, pg_data, progname, rmtree(), and xlog_dir.

{
    if (!noclean)
    {
        if (made_new_pgdata)
        {
            fprintf(stderr, _("%s: removing data directory \"%s\"\n"),
                    progname, pg_data);
            if (!rmtree(pg_data, true))
                fprintf(stderr, _("%s: failed to remove data directory\n"),
                        progname);
        }
        else if (found_existing_pgdata)
        {
            fprintf(stderr,
                    _("%s: removing contents of data directory \"%s\"\n"),
                    progname, pg_data);
            if (!rmtree(pg_data, false))
                fprintf(stderr, _("%s: failed to remove contents of data directory\n"),
                        progname);
        }

        if (made_new_xlogdir)
        {
            fprintf(stderr, _("%s: removing transaction log directory \"%s\"\n"),
                    progname, xlog_dir);
            if (!rmtree(xlog_dir, true))
                fprintf(stderr, _("%s: failed to remove transaction log directory\n"),
                        progname);
        }
        else if (found_existing_xlogdir)
        {
            fprintf(stderr,
            _("%s: removing contents of transaction log directory \"%s\"\n"),
                    progname, xlog_dir);
            if (!rmtree(xlog_dir, false))
                fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"),
                        progname);
        }
        /* otherwise died during startup, do nothing! */
    }
    else
    {
        if (made_new_pgdata || found_existing_pgdata)
            fprintf(stderr,
              _("%s: data directory \"%s\" not removed at user's request\n"),
                    progname, pg_data);

        if (made_new_xlogdir || found_existing_xlogdir)
            fprintf(stderr,
                    _("%s: transaction log directory \"%s\" not removed at user's request\n"),
                    progname, xlog_dir);
    }

    exit(1);
}

static char ** filter_lines_with_token ( char **  lines,
const char *  token 
) [static]

Definition at line 396 of file initdb.c.

References i, NULL, and pg_malloc().

Referenced by setup_config().

{
    int         numlines = 1;
    int         i,
                src,
                dst;
    char      **result;

    for (i = 0; lines[i]; i++)
        numlines++;

    result = (char **) pg_malloc(numlines * sizeof(char *));

    for (src = 0, dst = 0; src < numlines; src++)
    {
        if (lines[src] == NULL || strstr(lines[src], token) == NULL)
            result[dst++] = lines[src];
    }

    return result;
}

static const char* find_matching_ts_config ( const char *  lc_type  )  [static]

Definition at line 893 of file initdb.c.

References free, i, tsearch_config_match::langname, NULL, pg_strcasecmp(), pg_strdup(), and tsearch_config_match::tsconfname.

Referenced by setup_text_search().

{
    int         i;
    char       *langname,
               *ptr;

    /*
     * Convert lc_ctype to a language name by stripping everything after an
     * underscore (usual case) or a hyphen (Windows "locale name"; see
     * comments at IsoLocaleName()).
     *
     * XXX Should ' ' be a stop character?  This would select "norwegian" for
     * the Windows locale "Norwegian (Nynorsk)_Norway.1252".  If we do so, we
     * should also accept the "nn" and "nb" Unix locales.
     *
     * Just for paranoia, we also stop at '.' or '@'.
     */
    if (lc_type == NULL)
        langname = pg_strdup("");
    else
    {
        ptr = langname = pg_strdup(lc_type);
        while (*ptr &&
               *ptr != '_' && *ptr != '-' && *ptr != '.' && *ptr != '@')
            ptr++;
        *ptr = '\0';
    }

    for (i = 0; tsearch_config_languages[i].tsconfname; i++)
    {
        if (pg_strcasecmp(tsearch_config_languages[i].langname, langname) == 0)
        {
            free(langname);
            return tsearch_config_languages[i].tsconfname;
        }
    }

    free(langname);
    return NULL;
}

static void fsync_fname ( char *  fname,
bool  isdir 
) [static]

Definition at line 634 of file initdb.c.

References _, close, exit_nicely, fsync, PG_BINARY, progname, and strerror().

Referenced by perform_fsync().

{
    int         fd;
    int         returncode;

    /*
     * Some OSs require directories to be opened read-only whereas other
     * systems don't allow us to fsync files opened read-only; so we need both
     * cases here
     */
    if (!isdir)
        fd = open(fname, O_RDWR | PG_BINARY);
    else
        fd = open(fname, O_RDONLY | PG_BINARY);

    /*
     * Some OSs don't allow us to open directories at all (Windows returns
     * EACCES)
     */
    if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
        return;

    else if (fd < 0)
    {
        fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
                progname, fname, strerror(errno));
        exit_nicely();
    }

    returncode = fsync(fd);

    /* Some OSs don't allow us to fsync directories at all */
    if (returncode != 0 && isdir && errno == EBADF)
    {
        close(fd);
        return;
    }

    if (returncode != 0)
    {
        fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
                progname, fname, strerror(errno));
        exit_nicely();
    }

    close(fd);
}

static char * get_encoding_id ( char *  encoding_name  )  [static]

Definition at line 828 of file initdb.c.

References _, enc, encodingid_to_string(), pg_valid_server_encoding(), and progname.

Referenced by setup_locale_encoding().

{
    int         enc;

    if (encoding_name && *encoding_name)
    {
        if ((enc = pg_valid_server_encoding(encoding_name)) >= 0)
            return encodingid_to_string(enc);
    }
    fprintf(stderr, _("%s: \"%s\" is not a valid server encoding name\n"),
            progname, encoding_name ? encoding_name : "(null)");
    exit(1);
}

static char * get_id ( void   )  [static]

Definition at line 768 of file initdb.c.

References _, pg_strdup(), progname, and strerror().

Referenced by main().

{
#ifndef WIN32

    struct passwd *pw;

    if (geteuid() == 0)         /* 0 is root's uid */
    {
        fprintf(stderr,
                _("%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"),
                progname);
        exit(1);
    }

    pw = getpwuid(geteuid());
    if (!pw)
    {
        fprintf(stderr,
              _("%s: could not obtain information about current user: %s\n"),
                progname, strerror(errno));
        exit(1);
    }
#else                           /* the windows code */

    struct passwd_win32
    {
        int         pw_uid;
        char        pw_name[128];
    }           pass_win32;
    struct passwd_win32 *pw = &pass_win32;
    DWORD       pwname_size = sizeof(pass_win32.pw_name) - 1;

    pw->pw_uid = 1;
    if (!GetUserName(pw->pw_name, &pwname_size))
    {
        fprintf(stderr, _("%s: could not get current user name: %s\n"),
                progname, strerror(errno));
        exit(1);
    }
#endif

    return pg_strdup(pw->pw_name);
}

void get_restricted_token ( void   ) 

Definition at line 2819 of file initdb.c.

References _, NULL, pg_strdup(), progname, and putenv.

Referenced by main().

{
#ifdef WIN32
    /*
     * Before we execute another program, make sure that we are running with a
     * restricted token. If not, re-execute ourselves with one.
     */

    if ((restrict_env = getenv("PG_RESTRICT_EXEC")) == NULL
        || strcmp(restrict_env, "1") != 0)
    {
        PROCESS_INFORMATION pi;
        char       *cmdline;

        ZeroMemory(&pi, sizeof(pi));

        cmdline = pg_strdup(GetCommandLine());

        putenv("PG_RESTRICT_EXEC=1");

        if (!CreateRestrictedProcess(cmdline, &pi))
        {
            fprintf(stderr, _("%s: could not re-execute with restricted token: error code %lu\n"), progname, GetLastError());
        }
        else
        {
            /*
             * Successfully re-execed. Now wait for child process to capture
             * exitcode.
             */
            DWORD       x;

            CloseHandle(pi.hThread);
            WaitForSingleObject(pi.hProcess, INFINITE);

            if (!GetExitCodeProcess(pi.hProcess, &x))
            {
                fprintf(stderr, _("%s: could not get exit code from subprocess: error code %lu\n"), progname, GetLastError());
                exit(1);
            }
            exit(x);
        }
    }
#endif
}

static void get_set_pwd ( void   )  [static]

Definition at line 1504 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, escape_quotes(), exit_nicely, free, i, PG_CMD_PRINTF2, pg_strdup(), progname, pwfilename, pwprompt, simple_prompt(), snprintf(), strerror(), and username.

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;

    char       *pwd1,
               *pwd2;

    if (pwprompt)
    {
        /*
         * 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);
    }
    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;

        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 = pg_strdup(pwdbuf);

    }
    printf(_("setting password ... "));
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n",
                   username, escape_quotes(pwd1));

    /* MM: pwd1 is no longer needed, freeing it */
    free(pwd1);

    PG_CMD_CLOSE;

    check_ok();
}

void initialize_data_directory ( void   ) 

Definition at line 3329 of file initdb.c.

References _, bootstrap_template1(), check_ok(), create_data_directory(), create_xlog_symlink(), exit_nicely, get_set_pwd(), i, load_plpgsql(), make_postgres(), make_template0(), mkdatadir(), NULL, pwfilename, pwprompt, S_IRWXG, S_IRWXO, set_null_conf(), setup_auth(), setup_collation(), setup_config(), setup_conversion(), setup_depend(), setup_description(), setup_dictionary(), setup_privileges(), setup_schema(), setup_signals(), setup_sysviews(), subdirs, test_config_settings(), vacuum_db(), and write_version_file().

Referenced by main().

{
    int i;

    setup_signals();

    umask(S_IRWXG | S_IRWXO);
 
    create_data_directory();

    create_xlog_symlink();

    /* Create required subdirectories */
    printf(_("creating subdirectories ... "));
    fflush(stdout);

    for (i = 0; i < (sizeof(subdirs) / sizeof(char *)); i++)
    {
        if (!mkdatadir(subdirs[i]))
            exit_nicely();
    }

    check_ok();

    /* Top level PG_VERSION is checked by bootstrapper, so make it first */
    write_version_file(NULL);

    /* Select suitable configuration settings */
    set_null_conf();
    test_config_settings();

    /* Now create all the text config files */
    setup_config();

    /* Bootstrap template1 */
    bootstrap_template1();

    /*
     * Make the per-database PG_VERSION for template1 only after init'ing it
     */
    write_version_file("base/1");

    /* Create the stuff we don't need to use bootstrap mode for */

    setup_auth();
    if (pwprompt || pwfilename)
        get_set_pwd();

    setup_depend();

    setup_sysviews();

    setup_description();

    setup_collation();

    setup_conversion();

    setup_dictionary();

    setup_privileges();

    setup_schema();

    load_plpgsql();

    vacuum_db();

    make_template0();

    make_postgres();
}

static void load_plpgsql ( void   )  [static]

Definition at line 2169 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;

    fputs(_("loading PL/pgSQL server-side language ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n");

    PG_CMD_CLOSE;

    check_ok();
}

static int locale_date_order ( const char *  locale  )  [static]

Definition at line 2414 of file initdb.c.

References buf, free, my_strftime(), NULL, pg_strdup(), and tm.

Referenced by setup_config().

{
    struct tm   testtime;
    char        buf[128];
    char       *posD;
    char       *posM;
    char       *posY;
    char       *save;
    size_t      res;
    int         result;

    result = DATEORDER_MDY;     /* default */

    save = setlocale(LC_TIME, NULL);
    if (!save)
        return result;
    save = pg_strdup(save);

    setlocale(LC_TIME, locale);

    memset(&testtime, 0, sizeof(testtime));
    testtime.tm_mday = 22;
    testtime.tm_mon = 10;       /* November, should come out as "11" */
    testtime.tm_year = 133;     /* 2033 */

    res = my_strftime(buf, sizeof(buf), "%x", &testtime);

    setlocale(LC_TIME, save);
    free(save);

    if (res == 0)
        return result;

    posM = strstr(buf, "11");
    posD = strstr(buf, "22");
    posY = strstr(buf, "33");

    if (!posM || !posD || !posY)
        return result;

    if (posY < posM && posM < posD)
        result = DATEORDER_YMD;
    else if (posD < posM)
        result = DATEORDER_DMY;
    else
        result = DATEORDER_MDY;

    return result;
}

int main ( int  argc,
char *  argv[] 
)

Definition at line 3404 of file initdb.c.

References _, auth_methods_host, auth_methods_local, authmethodhost, authmethodlocal, authwarning, check_authmethod_unspecified(), check_authmethod_valid(), check_need_password(), data_checksums, debug, default_text_search_config, DIR_SEP, do_sync, encoding, get_id(), get_parent_directory(), get_progname(), get_restricted_token(), getopt_long(), initialize_data_directory(), lc_collate, lc_ctype, lc_messages, lc_monetary, lc_numeric, lc_time, locale, noclean, NULL, optarg, optind, perform_fsync(), pg_data, pg_strdup(), PG_TEXTDOMAIN, pgdata_native, progname, pwfilename, pwprompt, QUOTE_PATH, set_info_version(), set_pglocale_pgservice(), setup_bin_paths(), setup_data_file_paths(), setup_locale_encoding(), setup_pgdata(), setup_text_search(), share_path, show_setting, strlcpy(), sync_only, usage(), username, and xlog_dir.

{
    static struct option long_options[] = {
        {"pgdata", required_argument, NULL, 'D'},
        {"encoding", required_argument, NULL, 'E'},
        {"locale", required_argument, NULL, 1},
        {"lc-collate", required_argument, NULL, 2},
        {"lc-ctype", required_argument, NULL, 3},
        {"lc-monetary", required_argument, NULL, 4},
        {"lc-numeric", required_argument, NULL, 5},
        {"lc-time", required_argument, NULL, 6},
        {"lc-messages", required_argument, NULL, 7},
        {"no-locale", no_argument, NULL, 8},
        {"text-search-config", required_argument, NULL, 'T'},
        {"auth", required_argument, NULL, 'A'},
        {"auth-local", required_argument, NULL, 10},
        {"auth-host", required_argument, NULL, 11},
        {"pwprompt", no_argument, NULL, 'W'},
        {"pwfile", required_argument, NULL, 9},
        {"username", required_argument, NULL, 'U'},
        {"help", no_argument, NULL, '?'},
        {"version", no_argument, NULL, 'V'},
        {"debug", no_argument, NULL, 'd'},
        {"show", no_argument, NULL, 's'},
        {"noclean", no_argument, NULL, 'n'},
        {"nosync", no_argument, NULL, 'N'},
        {"sync-only", no_argument, NULL, 'S'},
        {"xlogdir", required_argument, NULL, 'X'},
        {"data-checksums", no_argument, NULL, 'k'},
        {NULL, 0, NULL, 0}
    };

    /*
     * options with no short version return a low integer, the rest return
     * their short version value
     */
    int         c;
    int         option_index;
    char       *effective_user;
    char        bin_dir[MAXPGPATH];

    progname = get_progname(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("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 ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
    {
        switch (c)
        {
            case 'A':
                authmethodlocal = authmethodhost = pg_strdup(optarg);

                /*
                 * When ident is specified, use peer for local connections.
                 * Mirrored, when peer is specified, use ident for TCP/IP
                 * connections.
                 */
                if (strcmp(authmethodhost, "ident") == 0)
                    authmethodlocal = "peer";
                else if (strcmp(authmethodlocal, "peer") == 0)
                    authmethodhost = "ident";
                break;
            case 10:
                authmethodlocal = pg_strdup(optarg);
                break;
            case 11:
                authmethodhost = pg_strdup(optarg);
                break;
            case 'D':
                pg_data = pg_strdup(optarg);
                break;
            case 'E':
                encoding = pg_strdup(optarg);
                break;
            case 'W':
                pwprompt = true;
                break;
            case 'U':
                username = pg_strdup(optarg);
                break;
            case 'd':
                debug = true;
                printf(_("Running in debug mode.\n"));
                break;
            case 'n':
                noclean = true;
                printf(_("Running in noclean mode.  Mistakes will not be cleaned up.\n"));
                break;
            case 'N':
                do_sync = false;
                break;
            case 'S':
                sync_only = true;
                break;
            case 'k':
                data_checksums = true;
                break;
            case 'L':
                share_path = pg_strdup(optarg);
                break;
            case 1:
                locale = pg_strdup(optarg);
                break;
            case 2:
                lc_collate = pg_strdup(optarg);
                break;
            case 3:
                lc_ctype = pg_strdup(optarg);
                break;
            case 4:
                lc_monetary = pg_strdup(optarg);
                break;
            case 5:
                lc_numeric = pg_strdup(optarg);
                break;
            case 6:
                lc_time = pg_strdup(optarg);
                break;
            case 7:
                lc_messages = pg_strdup(optarg);
                break;
            case 8:
                locale = "C";
                break;
            case 9:
                pwfilename = pg_strdup(optarg);
                break;
            case 's':
                show_setting = true;
                break;
            case 'T':
                default_text_search_config = pg_strdup(optarg);
                break;
            case 'X':
                xlog_dir = pg_strdup(optarg);
                break;
            default:
                /* getopt_long already emitted a complaint */
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                        progname);
                exit(1);
        }
    }


    /*
     * Non-option argument specifies data directory as long as it wasn't
     * already specified with -D / --pgdata
     */
    if (optind < argc && strlen(pg_data) == 0)
    {
        pg_data = pg_strdup(argv[optind]);
        optind++;
    }

    if (optind < argc)
    {
        fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
                progname, argv[optind]);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }

    /* If we only need to fsync, just to it and exit */
    if (sync_only)
    {
        setup_pgdata();
        perform_fsync();
        return 0;
    }
    
    if (pwprompt && pwfilename)
    {
        fprintf(stderr, _("%s: password prompt and password file cannot be specified together\n"), progname);
        exit(1);
    }

    check_authmethod_unspecified(&authmethodlocal);
    check_authmethod_unspecified(&authmethodhost);

    check_authmethod_valid(authmethodlocal, auth_methods_local, "local");
    check_authmethod_valid(authmethodhost, auth_methods_host, "host");

    check_need_password(authmethodlocal, authmethodhost);

    get_restricted_token();

    setup_pgdata();

    setup_bin_paths(argv[0]);
    
    effective_user = get_id();
    if (strlen(username) == 0)
        username = effective_user;

    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"),
           effective_user);

    set_info_version();

    setup_data_file_paths();

    setup_locale_encoding();

    setup_text_search();

    if (data_checksums)
        printf(_("Data page checksums are enabled.\n"));
    else
        printf(_("Data page checksums are disabled.\n"));
    
    printf("\n");

    initialize_data_directory();
    
    if (do_sync)
        perform_fsync();
    else
        printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n"));

    if (authwarning != NULL)
        fprintf(stderr, "%s", authwarning);

    /* Get directory specification used to start this executable */
    strlcpy(bin_dir, argv[0], sizeof(bin_dir));
    get_parent_directory(bin_dir);

    printf(_("\nSuccess. You can now start the database server using:\n\n"
             "    %s%s%spostgres%s -D %s%s%s\n"
             "or\n"
             "    %s%s%spg_ctl%s -D %s%s%s -l logfile start\n\n"),
       QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
           QUOTE_PATH, pgdata_native, QUOTE_PATH,
       QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
           QUOTE_PATH, pgdata_native, QUOTE_PATH);

    return 0;
}

static void make_postgres ( void   )  [static]

Definition at line 2276 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, NULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    const char **line;
    static const char *postgres_setup[] = {
        "CREATE DATABASE postgres;\n",
        "COMMENT ON DATABASE postgres IS 'default administrative connection database';\n",
        NULL
    };

    fputs(_("copying template1 to postgres ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = postgres_setup; *line; line++)
        PG_CMD_PUTS(*line);

    PG_CMD_CLOSE;

    check_ok();
}

static void make_template0 ( void   )  [static]

Definition at line 2219 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, NULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    const char **line;
    static const char *template0_setup[] = {
        "CREATE DATABASE template0;\n",
        "UPDATE pg_database SET "
        "   datistemplate = 't', "
        "   datallowconn = 'f' "
        "    WHERE datname = 'template0';\n",

        /*
         * We use the OID of template0 to determine lastsysoid
         */
        "UPDATE pg_database SET datlastsysoid = "
        "    (SELECT oid FROM pg_database "
        "    WHERE datname = 'template0');\n",

        /*
         * Explicitly revoke public create-schema and create-temp-table
         * privileges in template1 and template0; else the latter would be on
         * by default
         */
        "REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n",
        "REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n",

        "COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n",

        /*
         * Finally vacuum to clean up dead rows in pg_database
         */
        "VACUUM FULL pg_database;\n",
        NULL
    };

    fputs(_("copying template1 to template0 ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = template0_setup; *line; line++)
        PG_CMD_PUTS(*line);

    PG_CMD_CLOSE;

    check_ok();
}

static bool mkdatadir ( const char *  subdir  )  [static]

Definition at line 939 of file initdb.c.

References _, NULL, pg_data, pg_malloc(), pg_mkdir_p(), progname, and strerror().

Referenced by create_data_directory(), and initialize_data_directory().

{
    char       *path;

    path = pg_malloc(strlen(pg_data) + 2 +
                     (subdir == NULL ? 0 : strlen(subdir)));

    if (subdir != NULL)
        sprintf(path, "%s/%s", pg_data, subdir);
    else
        strcpy(path, pg_data);

    if (pg_mkdir_p(path, S_IRWXU) == 0)
        return true;

    fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
            progname, path, strerror(errno));

    return false;
}

static size_t my_strftime ( char *  s,
size_t  max,
const char *  fmt,
const struct tm tm 
) [inline, static]

Definition at line 2405 of file initdb.c.

Referenced by locale_date_order().

{
    return strftime(s, max, fmt, tm);
}

static void perform_fsync ( void   )  [static]

Definition at line 2308 of file initdb.c.

References _, canonicalize_path(), check_ok(), fsync_fname(), MAXPGPATH, pg_data, pre_sync_fname(), snprintf(), and walkdir().

Referenced by main().

{
    char        pdir[MAXPGPATH];

    fputs(_("syncing data to disk ... "), stdout);
    fflush(stdout);

    /*
     * We need to name the parent of PGDATA.  get_parent_directory() isn't
     * enough here, because it can result in an empty string.
     */
    snprintf(pdir, MAXPGPATH, "%s/..", pg_data);
    canonicalize_path(pdir);

    /*
     * Hint to the OS so that we're going to fsync each of these files soon.
     */

    /* first the parent of the PGDATA directory */
    pre_sync_fname(pdir, true);

    /* then recursively through the directory */
    walkdir(pg_data, pre_sync_fname);

    /*
     * Now, do the fsync()s in the same order.
     */

    /* first the parent of the PGDATA directory */
    fsync_fname(pdir, true);

    /* then recursively through the directory */
    walkdir(pg_data, fsync_fname);

    check_ok();
}

static FILE * popen_check ( const char *  command,
const char *  mode 
) [static]

Definition at line 686 of file initdb.c.

References _, NULL, progname, and strerror().

Referenced by setup_collation().

{
    FILE       *cmdfd;

    fflush(stdout);
    fflush(stderr);
    errno = 0;
    cmdfd = popen(command, mode);
    if (cmdfd == NULL)
        fprintf(stderr, _("%s: could not execute command \"%s\": %s\n"),
                progname, command, strerror(errno));
    return cmdfd;
}

static void pre_sync_fname ( char *  fname,
bool  isdir 
) [static]

Definition at line 589 of file initdb.c.

References _, close, exit_nicely, PG_BINARY, progname, and strerror().

Referenced by perform_fsync().

{
#if defined(HAVE_SYNC_FILE_RANGE) || \
    (defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED))
    int fd;

    fd = open(fname, O_RDONLY | PG_BINARY);

    /*
     * Some OSs don't allow us to open directories at all (Windows returns
     * EACCES)
     */
    if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
        return;

    if (fd < 0)
    {
        fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
                progname, fname, strerror(errno));
        exit_nicely();
    }

    /*
     * Prefer sync_file_range, else use posix_fadvise.  We ignore any error
     * here since this operation is only a hint anyway.
     */
#if defined(HAVE_SYNC_FILE_RANGE)
    sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
    posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
#endif

    close(fd);
#endif
}

static char ** readfile ( const char *  path  )  [static]

Definition at line 423 of file initdb.c.

References _, exit_nicely, free, NULL, pg_malloc(), pg_strdup(), progname, and strerror().

Referenced by bootstrap_template1(), setup_config(), setup_conversion(), setup_dictionary(), setup_schema(), and setup_sysviews().

{
    FILE       *infile;
    int         maxlength = 1,
                linelen = 0;
    int         nlines = 0;
    int         n;
    char      **result;
    char       *buffer;
    int         c;

    if ((infile = fopen(path, "r")) == NULL)
    {
        fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }

    /* pass over the file twice - the first time to size the result */

    while ((c = fgetc(infile)) != EOF)
    {
        linelen++;
        if (c == '\n')
        {
            nlines++;
            if (linelen > maxlength)
                maxlength = linelen;
            linelen = 0;
        }
    }

    /* handle last line without a terminating newline (yuck) */
    if (linelen)
        nlines++;
    if (linelen > maxlength)
        maxlength = linelen;

    /* set up the result and the line buffer */
    result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
    buffer = (char *) pg_malloc(maxlength + 1);

    /* now reprocess the file and store the lines */
    rewind(infile);
    n = 0;
    while (fgets(buffer, maxlength + 1, infile) != NULL && n < nlines)
        result[n++] = pg_strdup(buffer);

    fclose(infile);
    free(buffer);
    result[n] = NULL;

    return result;
}

static char ** replace_token ( char **  lines,
const char *  token,
const char *  replacement 
) [static]

Definition at line 340 of file initdb.c.

References i, NULL, and pg_malloc().

Referenced by bootstrap_template1(), setup_config(), and setup_privileges().

{
    int         numlines = 1;
    int         i;
    char      **result;
    int         toklen,
                replen,
                diff;

    for (i = 0; lines[i]; i++)
        numlines++;

    result = (char **) pg_malloc(numlines * sizeof(char *));

    toklen = strlen(token);
    replen = strlen(replacement);
    diff = replen - toklen;

    for (i = 0; i < numlines; i++)
    {
        char       *where;
        char       *newline;
        int         pre;

        /* just copy pointer if NULL or no change needed */
        if (lines[i] == NULL || (where = strstr(lines[i], token)) == NULL)
        {
            result[i] = lines[i];
            continue;
        }

        /* if we get here a change is needed - set up new line */

        newline = (char *) pg_malloc(strlen(lines[i]) + diff + 1);

        pre = where - lines[i];

        strncpy(newline, lines[i], pre);

        strcpy(newline + pre, replacement);

        strcpy(newline + pre + replen, lines[i] + pre + toklen);

        result[i] = newline;
    }

    return result;
}

const char* select_default_timezone ( const char *  share_path  ) 

Definition at line 1204 of file findtimezone.c.

References identify_system_timezone(), snprintf(), tzdirpath, and validate_zone().

Referenced by setup_config().

{
    const char *tzname;

    /* Initialize timezone directory path, if needed */
#ifndef SYSTEMTZDIR
    snprintf(tzdirpath, sizeof(tzdirpath), "%s/timezone", share_path);
#endif

    /* Check TZ environment variable */
    tzname = getenv("TZ");
    if (validate_zone(tzname))
        return tzname;

    /* Nope, so try to identify the system timezone */
    tzname = identify_system_timezone();
    if (validate_zone(tzname))
        return tzname;

    return NULL;
}

static void set_info_version ( void   )  [static]

Definition at line 2084 of file initdb.c.

References infoversion, pg_strdup(), and snprintf().

Referenced by main().

{
    char       *letterversion;
    long        major = 0,
                minor = 0,
                micro = 0;
    char       *endptr;
    char       *vstr = pg_strdup(PG_VERSION);
    char       *ptr;

    ptr = vstr + (strlen(vstr) - 1);
    while (ptr != vstr && (*ptr < '0' || *ptr > '9'))
        ptr--;
    letterversion = ptr + 1;
    major = strtol(vstr, &endptr, 10);
    if (*endptr)
        minor = strtol(endptr + 1, &endptr, 10);
    if (*endptr)
        micro = strtol(endptr + 1, &endptr, 10);
    snprintf(infoversion, sizeof(infoversion), "%02ld.%02ld.%04ld%s",
             major, minor, micro, letterversion);
}

static void set_input ( char **  dest,
char *  filename 
) [static]

Definition at line 965 of file initdb.c.

References pg_malloc(), and share_path.

Referenced by setup_data_file_paths().

{
    *dest = pg_malloc(strlen(share_path) + strlen(filename) + 2);
    sprintf(*dest, "%s/%s", share_path, filename);
}

static void set_null_conf ( void   )  [static]

Definition at line 1053 of file initdb.c.

References _, conf_file, exit_nicely, free, NULL, PG_BINARY_W, pg_data, pg_malloc(), progname, and strerror().

Referenced by initialize_data_directory().

{
    FILE       *conf_file;
    char       *path;

    path = pg_malloc(strlen(pg_data) + 17);
    sprintf(path, "%s/postgresql.conf", pg_data);
    conf_file = fopen(path, PG_BINARY_W);
    if (conf_file == NULL)
    {
        fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    if (fclose(conf_file))
    {
        fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    free(path);
}

static void setlocales ( void   )  [static]

Definition at line 2555 of file initdb.c.

References check_locale_name(), lc_collate, lc_ctype, lc_messages, lc_monetary, lc_numeric, lc_time, locale, NULL, and pg_strdup().

Referenced by setup_locale_encoding().

{
    char       *canonname;

    /* set empty lc_* values to locale config if set */

    if (strlen(locale) > 0)
    {
        if (strlen(lc_ctype) == 0)
            lc_ctype = locale;
        if (strlen(lc_collate) == 0)
            lc_collate = locale;
        if (strlen(lc_numeric) == 0)
            lc_numeric = locale;
        if (strlen(lc_time) == 0)
            lc_time = locale;
        if (strlen(lc_monetary) == 0)
            lc_monetary = locale;
        if (strlen(lc_messages) == 0)
            lc_messages = locale;
    }

    /*
     * canonicalize locale names, and override any missing/invalid values from
     * our current environment
     */

    if (check_locale_name(LC_CTYPE, lc_ctype, &canonname))
        lc_ctype = canonname;
    else
        lc_ctype = pg_strdup(setlocale(LC_CTYPE, NULL));
    if (check_locale_name(LC_COLLATE, lc_collate, &canonname))
        lc_collate = canonname;
    else
        lc_collate = pg_strdup(setlocale(LC_COLLATE, NULL));
    if (check_locale_name(LC_NUMERIC, lc_numeric, &canonname))
        lc_numeric = canonname;
    else
        lc_numeric = pg_strdup(setlocale(LC_NUMERIC, NULL));
    if (check_locale_name(LC_TIME, lc_time, &canonname))
        lc_time = canonname;
    else
        lc_time = pg_strdup(setlocale(LC_TIME, NULL));
    if (check_locale_name(LC_MONETARY, lc_monetary, &canonname))
        lc_monetary = canonname;
    else
        lc_monetary = pg_strdup(setlocale(LC_MONETARY, NULL));
#if defined(LC_MESSAGES) && !defined(WIN32)
    if (check_locale_name(LC_MESSAGES, lc_messages, &canonname))
        lc_messages = canonname;
    else
        lc_messages = pg_strdup(setlocale(LC_MESSAGES, NULL));
#else
    /* when LC_MESSAGES is not available, use the LC_CTYPE setting */
    if (check_locale_name(LC_CTYPE, lc_messages, &canonname))
        lc_messages = canonname;
    else
        lc_messages = pg_strdup(setlocale(LC_CTYPE, NULL));
#endif
}

static void setup_auth ( void   )  [static]

Definition at line 1469 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, NULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    const char **line;
    static const char *pg_authid_setup[] = {
        /*
         * The authid table shouldn't be readable except through views, to
         * ensure passwords are not publicly visible.
         */
        "REVOKE ALL on pg_authid FROM public;\n",
        NULL
    };

    fputs(_("initializing pg_authid ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = pg_authid_setup; *line != NULL; line++)
        PG_CMD_PUTS(*line);

    PG_CMD_CLOSE;

    check_ok();
}

void setup_bin_paths ( const char *  argv0  ) 

Definition at line 2906 of file initdb.c.

References _, backend_exec, bin_path, canonicalize_path(), find_my_exec(), find_other_exec(), get_share_path(), is_absolute_path, last_dir_separator(), MAXPGPATH, PG_BACKEND_VERSIONSTR, pg_malloc(), progname, share_path, and strlcpy().

Referenced by main().

{
    int ret;

    if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
                               backend_exec)) < 0)
    {
        char        full_path[MAXPGPATH];

        if (find_my_exec(argv0, full_path) < 0)
            strlcpy(full_path, progname, sizeof(full_path));

        if (ret == -1)
            fprintf(stderr,
                    _("The program \"postgres\" is needed by %s "
                      "but was not found in the\n"
                      "same directory as \"%s\".\n"
                      "Check your installation.\n"),
                    progname, full_path);
        else
            fprintf(stderr,
                    _("The program \"postgres\" was found by \"%s\"\n"
                      "but was not the same version as %s.\n"
                      "Check your installation.\n"),
                    full_path, progname);
        exit(1);
    }

    /* store binary directory */
    strcpy(bin_path, backend_exec);
    *last_dir_separator(bin_path) = '\0';
    canonicalize_path(bin_path);

    if (!share_path)
    {
        share_path = pg_malloc(MAXPGPATH);
        get_share_path(backend_exec, share_path);
    }
    else if (!is_absolute_path(share_path))
    {
        fprintf(stderr, _("%s: input file location must be an absolute path\n"), progname);
        exit(1);
    }

    canonicalize_path(share_path);
}

static void setup_collation ( void   )  [static]

Definition at line 1819 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), debug, DEVNULL, enc, escape_quotes(), i, IS_HIGHBIT_SET, PG_CMD_PRINTF1, PG_CMD_PRINTF3, PG_CMD_PUTS, pg_get_encoding_from_locale(), PG_SQL_ASCII, PG_UTF8, PG_VALID_BE_ENCODING, popen_check(), progname, and snprintf().

Referenced by initialize_data_directory().

{
#if defined(HAVE_LOCALE_T) && !defined(WIN32)
    int         i;
    FILE       *locale_a_handle;
    char        localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
    int         count = 0;

    PG_CMD_DECL;
#endif

    fputs(_("creating collations ... "), stdout);
    fflush(stdout);

#if defined(HAVE_LOCALE_T) && !defined(WIN32)
    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    locale_a_handle = popen_check("locale -a", "r");
    if (!locale_a_handle)
        return;                 /* complaint already printed */

    PG_CMD_OPEN;

    PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_collation ( "
                "   collname name, "
                "   locale name, "
                "   encoding int) WITHOUT OIDS;\n");

    while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
    {
        size_t      len;
        int         enc;
        bool        skip;
        char       *quoted_locale;
        char        alias[NAMEDATALEN];

        len = strlen(localebuf);

        if (len == 0 || localebuf[len - 1] != '\n')
        {
            if (debug)
                fprintf(stderr, _("%s: locale name too long, skipped: \"%s\"\n"),
                        progname, localebuf);
            continue;
        }
        localebuf[len - 1] = '\0';

        /*
         * Some systems have locale names that don't consist entirely of ASCII
         * letters (such as "bokm&aring;l" or "fran&ccedil;ais").  This is
         * pretty silly, since we need the locale itself to interpret the
         * non-ASCII characters. We can't do much with those, so we filter
         * them out.
         */
        skip = false;
        for (i = 0; i < len; i++)
        {
            if (IS_HIGHBIT_SET(localebuf[i]))
            {
                skip = true;
                break;
            }
        }
        if (skip)
        {
            if (debug)
                fprintf(stderr, _("%s: locale name has non-ASCII characters, skipped: \"%s\"\n"),
                        progname, localebuf);
            continue;
        }

        enc = pg_get_encoding_from_locale(localebuf, debug);
        if (enc < 0)
        {
            /* error message printed by pg_get_encoding_from_locale() */
            continue;
        }
        if (!PG_VALID_BE_ENCODING(enc))
            continue;           /* ignore locales for client-only encodings */
        if (enc == PG_SQL_ASCII)
            continue;           /* C/POSIX are already in the catalog */

        count++;

        quoted_locale = escape_quotes(localebuf);

        PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
                       quoted_locale, quoted_locale, enc);

        /*
         * Generate aliases such as "en_US" in addition to "en_US.utf8" for
         * ease of use.  Note that collation names are unique per encoding
         * only, so this doesn't clash with "en_US" for LATIN1, say.
         */
        if (normalize_locale_name(alias, localebuf))
            PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
                           escape_quotes(alias), quoted_locale, enc);
    }

    /* Add an SQL-standard name */
    PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n", PG_UTF8);

    /*
     * When copying collations to the final location, eliminate aliases that
     * conflict with an existing locale name for the same encoding.  For
     * example, "br_FR.iso88591" is normalized to "br_FR", both for encoding
     * LATIN1.  But the unnormalized locale "br_FR" already exists for LATIN1.
     * Prefer the alias that matches the OS locale name, else the first locale
     * name by sort order (arbitrary choice to be deterministic).
     *
     * Also, eliminate any aliases that conflict with pg_collation's
     * hard-wired entries for "C" etc.
     */
    PG_CMD_PUTS("INSERT INTO pg_collation (collname, collnamespace, collowner, collencoding, collcollate, collctype) "
                " SELECT DISTINCT ON (collname, encoding)"
                "   collname, "
                "   (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') AS collnamespace, "
                "   (SELECT relowner FROM pg_class WHERE relname = 'pg_collation') AS collowner, "
                "   encoding, locale, locale "
                "  FROM tmp_pg_collation"
                "  WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)"
       "  ORDER BY collname, encoding, (collname = locale) DESC, locale;\n");

    pclose(locale_a_handle);
    PG_CMD_CLOSE;

    check_ok();
    if (count == 0 && !debug)
    {
        printf(_("No usable system locales were found.\n"));
        printf(_("Use the option \"--debug\" to see details.\n"));
    }
#else                           /* not HAVE_LOCALE_T && not WIN32 */
    printf(_("not supported on this platform\n"));
    fflush(stdout);
#endif   /* not HAVE_LOCALE_T  && not WIN32 */
}

static void setup_config ( void   )  [static]

Definition at line 1177 of file initdb.c.

References _, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_canonname, addrinfo::ai_family, addrinfo::ai_flags, addrinfo::ai_next, addrinfo::ai_protocol, addrinfo::ai_socktype, authmethodhost, authmethodlocal, AUTHTRUST_WARNING, check_ok(), conf_file, DATEORDER_DMY, DATEORDER_MDY, DATEORDER_YMD, DEFAULT_PGSOCKET_DIR, default_text_search_config, escape_quotes(), filter_lines_with_token(), free, getaddrinfo, hba_file, ident_file, lc_messages, lc_monetary, lc_numeric, lc_time, locale_date_order(), n_buffers, n_connections, NULL, pg_data, readfile(), replace_token(), select_default_timezone(), share_path, snprintf(), username, and writefile().

Referenced by initialize_data_directory().

{
    char      **conflines;
    char        repltok[MAXPGPATH];
    char        path[MAXPGPATH];
    const char *default_timezone;

    fputs(_("creating configuration files ... "), stdout);
    fflush(stdout);

    /* postgresql.conf */

    conflines = readfile(conf_file);

    snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections);
    conflines = replace_token(conflines, "#max_connections = 100", repltok);

    if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
        snprintf(repltok, sizeof(repltok), "shared_buffers = %dMB",
                 (n_buffers * (BLCKSZ / 1024)) / 1024);
    else
        snprintf(repltok, sizeof(repltok), "shared_buffers = %dkB",
                 n_buffers * (BLCKSZ / 1024));
    conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);

#ifdef HAVE_UNIX_SOCKETS
    snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
             DEFAULT_PGSOCKET_DIR);
#else
    snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
#endif
    conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
                              repltok);

#if DEF_PGPORT != 5432
    snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
    conflines = replace_token(conflines, "#port = 5432", repltok);
#endif

    snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
             escape_quotes(lc_messages));
    conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);

    snprintf(repltok, sizeof(repltok), "lc_monetary = '%s'",
             escape_quotes(lc_monetary));
    conflines = replace_token(conflines, "#lc_monetary = 'C'", repltok);

    snprintf(repltok, sizeof(repltok), "lc_numeric = '%s'",
             escape_quotes(lc_numeric));
    conflines = replace_token(conflines, "#lc_numeric = 'C'", repltok);

    snprintf(repltok, sizeof(repltok), "lc_time = '%s'",
             escape_quotes(lc_time));
    conflines = replace_token(conflines, "#lc_time = 'C'", repltok);

    switch (locale_date_order(lc_time))
    {
        case DATEORDER_YMD:
            strcpy(repltok, "datestyle = 'iso, ymd'");
            break;
        case DATEORDER_DMY:
            strcpy(repltok, "datestyle = 'iso, dmy'");
            break;
        case DATEORDER_MDY:
        default:
            strcpy(repltok, "datestyle = 'iso, mdy'");
            break;
    }
    conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok);

    snprintf(repltok, sizeof(repltok),
             "default_text_search_config = 'pg_catalog.%s'",
             escape_quotes(default_text_search_config));
    conflines = replace_token(conflines,
                         "#default_text_search_config = 'pg_catalog.simple'",
                              repltok);

    default_timezone = select_default_timezone(share_path);
    if (default_timezone)
    {
        snprintf(repltok, sizeof(repltok), "timezone = '%s'",
                 escape_quotes(default_timezone));
        conflines = replace_token(conflines, "#timezone = 'GMT'", repltok);
        snprintf(repltok, sizeof(repltok), "log_timezone = '%s'",
                 escape_quotes(default_timezone));
        conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
    }

    snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);

    writefile(path, conflines);
    chmod(path, S_IRUSR | S_IWUSR);

    free(conflines);


    /* pg_hba.conf */

    conflines = readfile(hba_file);

#ifndef HAVE_UNIX_SOCKETS
    conflines = filter_lines_with_token(conflines, "@[email protected]");
#else
    conflines = replace_token(conflines, "@[email protected]", "");
#endif

#ifdef HAVE_IPV6

    /*
     * Probe to see if there is really any platform support for IPv6, and
     * comment out the relevant pg_hba line if not.  This avoids runtime
     * warnings if getaddrinfo doesn't actually cope with IPv6.  Particularly
     * useful on Windows, where executables built on a machine with IPv6 may
     * have to run on a machine without.
     */
    {
        struct addrinfo *gai_result;
        struct addrinfo hints;
        int         err = 0;

#ifdef WIN32
        /* need to call WSAStartup before calling getaddrinfo */
        WSADATA     wsaData;

        err = WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

        /* for best results, this code should match parse_hba() */
        hints.ai_flags = AI_NUMERICHOST;
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = 0;
        hints.ai_protocol = 0;
        hints.ai_addrlen = 0;
        hints.ai_canonname = NULL;
        hints.ai_addr = NULL;
        hints.ai_next = NULL;

        if (err != 0 ||
            getaddrinfo("::1", NULL, &hints, &gai_result) != 0)
            conflines = replace_token(conflines,
                               "host    all             all             ::1",
                             "#host    all             all             ::1");
    }
#else                           /* !HAVE_IPV6 */
    /* If we didn't compile IPV6 support at all, always comment it out */
    conflines = replace_token(conflines,
                              "host    all             all             ::1",
                              "#host    all             all             ::1");
#endif   /* HAVE_IPV6 */

    /* Replace default authentication methods */
    conflines = replace_token(conflines,
                              "@[email protected]",
                              authmethodhost);
    conflines = replace_token(conflines,
                              "@[email protected]",
                              authmethodlocal);

    conflines = replace_token(conflines,
                              "@[email protected]",
                              (strcmp(authmethodlocal, "trust") == 0 || strcmp(authmethodhost, "trust") == 0) ? AUTHTRUST_WARNING : "");

    /* Replace username for replication */
    conflines = replace_token(conflines,
                              "@[email protected]",
                              username);

    snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);

    writefile(path, conflines);
    chmod(path, S_IRUSR | S_IWUSR);

    free(conflines);

    /* pg_ident.conf */

    conflines = readfile(ident_file);

    snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data);

    writefile(path, conflines);
    chmod(path, S_IRUSR | S_IWUSR);

    free(conflines);

    check_ok();
}

static void setup_conversion ( void   )  [static]

Definition at line 1964 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), conversion_file, DEVNULL, free, PG_CMD_PUTS, readfile(), and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char      **conv_lines;

    fputs(_("creating conversions ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    conv_lines = readfile(conversion_file);
    for (line = conv_lines; *line != NULL; line++)
    {
        if (strstr(*line, "DROP CONVERSION") != *line)
            PG_CMD_PUTS(*line);
        free(*line);
    }

    free(conv_lines);

    PG_CMD_CLOSE;

    check_ok();
}

void setup_data_file_paths ( void   ) 

Definition at line 3043 of file initdb.c.

References bin_path, bki_file, check_input(), conf_file, conversion_file, debug, desc_file, dictionary_file, features_file, hba_file, ident_file, info_schema_file, pg_data, set_input(), share_path, shdesc_file, show_setting, system_views_file, and username.

Referenced by main().

{
    set_input(&bki_file, "postgres.bki");
    set_input(&desc_file, "postgres.description");
    set_input(&shdesc_file, "postgres.shdescription");
    set_input(&hba_file, "pg_hba.conf.sample");
    set_input(&ident_file, "pg_ident.conf.sample");
    set_input(&conf_file, "postgresql.conf.sample");
    set_input(&conversion_file, "conversion_create.sql");
    set_input(&dictionary_file, "snowball_create.sql");
    set_input(&info_schema_file, "information_schema.sql");
    set_input(&features_file, "sql_features.txt");
    set_input(&system_views_file, "system_views.sql");

    if (show_setting || debug)
    {
        fprintf(stderr,
                "VERSION=%s\n"
                "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
                "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
                "POSTGRES_DESCR=%s\nPOSTGRES_SHDESCR=%s\n"
                "POSTGRESQL_CONF_SAMPLE=%s\n"
                "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
                PG_VERSION,
                pg_data, share_path, bin_path,
                username, bki_file,
                desc_file, shdesc_file,
                conf_file,
                hba_file, ident_file);
        if (show_setting)
            exit(0);
    }

    check_input(bki_file);
    check_input(desc_file);
    check_input(shdesc_file);
    check_input(hba_file);
    check_input(ident_file);
    check_input(conf_file);
    check_input(conversion_file);
    check_input(dictionary_file);
    check_input(info_schema_file);
    check_input(features_file);
    check_input(system_views_file);
}

static void setup_depend ( void   )  [static]

Definition at line 1585 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, NULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    const char **line;
    static const char *pg_depend_setup[] = {
        /*
         * Make PIN entries in pg_depend for all objects made so far in the
         * tables that the dependency code handles.  This is overkill (the
         * system doesn't really depend on having every last weird datatype,
         * for instance) but generating only the minimum required set of
         * dependencies seems hard.
         *
         * Note that we deliberately do not pin the system views, which
         * haven't been created yet.  Also, no conversions, databases, or
         * tablespaces are pinned.
         *
         * First delete any already-made entries; PINs override all else, and
         * must be the only entries for their objects.
         */
        "DELETE FROM pg_depend;\n",
        "VACUUM pg_depend;\n",
        "DELETE FROM pg_shdepend;\n",
        "VACUUM pg_shdepend;\n",

        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_class;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_proc;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_type;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_cast;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_constraint;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_attrdef;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_language;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_operator;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_opclass;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_opfamily;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_amop;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_amproc;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_rewrite;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_trigger;\n",

        /*
         * restriction here to avoid pinning the public namespace
         */
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_namespace "
        "    WHERE nspname LIKE 'pg%';\n",

        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_ts_parser;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_ts_dict;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_ts_template;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_ts_config;\n",
        "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
        " FROM pg_collation;\n",
        "INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
        " FROM pg_authid;\n",
        NULL
    };

    fputs(_("initializing dependencies ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = pg_depend_setup; *line != NULL; line++)
        PG_CMD_PUTS(*line);

    PG_CMD_CLOSE;

    check_ok();
}

static void setup_description ( void   )  [static]

Definition at line 1720 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), desc_file, DEVNULL, escape_quotes(), PG_CMD_PRINTF1, PG_CMD_PUTS, shdesc_file, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;

    fputs(_("loading system objects' descriptions ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_description ( "
                "   objoid oid, "
                "   classname name, "
                "   objsubid int4, "
                "   description text) WITHOUT OIDS;\n");

    PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n",
                   escape_quotes(desc_file));

    PG_CMD_PUTS("INSERT INTO pg_description "
                " SELECT t.objoid, c.oid, t.objsubid, t.description "
                "  FROM tmp_pg_description t, pg_class c "
                "    WHERE c.relname = t.classname;\n");

    PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( "
                " objoid oid, "
                " classname name, "
                " description text) WITHOUT OIDS;\n");

    PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n",
                   escape_quotes(shdesc_file));

    PG_CMD_PUTS("INSERT INTO pg_shdescription "
                " SELECT t.objoid, c.oid, t.description "
                "  FROM tmp_pg_shdescription t, pg_class c "
                "   WHERE c.relname = t.classname;\n");

    /* Create default descriptions for operator implementation functions */
    PG_CMD_PUTS("WITH funcdescs AS ( "
                "SELECT p.oid as p_oid, oprname, "
              "coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc "
                "FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid ) "
                "INSERT INTO pg_description "
                "  SELECT p_oid, 'pg_proc'::regclass, 0, "
                "    'implementation of ' || oprname || ' operator' "
                "  FROM funcdescs "
                "  WHERE opdesc NOT LIKE 'deprecated%' AND "
                "  NOT EXISTS (SELECT 1 FROM pg_description "
          "    WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass);\n");

    PG_CMD_CLOSE;

    check_ok();
}

static void setup_dictionary ( void   )  [static]

Definition at line 1999 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, dictionary_file, free, PG_CMD_PUTS, readfile(), and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char      **conv_lines;

    fputs(_("creating dictionaries ... "), stdout);
    fflush(stdout);

    /*
     * We use -j here to avoid backslashing stuff
     */
    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s -j template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    conv_lines = readfile(dictionary_file);
    for (line = conv_lines; *line != NULL; line++)
    {
        PG_CMD_PUTS(*line);
        free(*line);
    }

    free(conv_lines);

    PG_CMD_CLOSE;

    check_ok();
}

void setup_locale_encoding ( void   ) 

Definition at line 2954 of file initdb.c.

References _, check_locale_encoding(), encoding, encodingid, encodingid_to_string(), get_encoding_id(), lc_collate, lc_ctype, lc_messages, lc_monetary, lc_numeric, lc_time, pg_encoding_to_char(), pg_get_encoding_from_locale(), PG_UTF8, pg_valid_server_encoding_id(), progname, and setlocales().

Referenced by main().

{
    int         user_enc;

    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"), lc_ctype);
    else
    {
        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"),
               lc_collate,
               lc_ctype,
               lc_messages,
               lc_monetary,
               lc_numeric,
               lc_time);
    }

    if (strlen(encoding) == 0)
    {
        int         ctype_enc;

        ctype_enc = pg_get_encoding_from_locale(lc_ctype, true);

        if (ctype_enc == -1)
        {
            /* Couldn't recognize the locale's codeset */
            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 if (!pg_valid_server_encoding_id(ctype_enc))
        {
            /*
             * We recognized it, but it's not a legal server encoding. On
             * Windows, UTF-8 works with any locale, so we can fall back to
             * UTF-8.
             */
#ifdef WIN32
            printf(_("Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n"
            "The default database encoding will be set to \"%s\" instead.\n"),
                   pg_encoding_to_char(ctype_enc),
                   pg_encoding_to_char(PG_UTF8));
            ctype_enc = PG_UTF8;
            encodingid = encodingid_to_string(ctype_enc);
#else
            fprintf(stderr,
               _("%s: locale \"%s\" requires unsupported encoding \"%s\"\n"),
                    progname, lc_ctype, pg_encoding_to_char(ctype_enc));
            fprintf(stderr,
              _("Encoding \"%s\" is not allowed as a server-side encoding.\n"
                "Rerun %s with a different locale selection.\n"),
                    pg_encoding_to_char(ctype_enc), progname);
            exit(1);
#endif
        }
        else
        {
            encodingid = encodingid_to_string(ctype_enc);
            printf(_("The default database encoding has accordingly been set to \"%s\".\n"),
                   pg_encoding_to_char(ctype_enc));
        }
    }
    else
        encodingid = get_encoding_id(encoding);

    user_enc = atoi(encodingid);
    if (!check_locale_encoding(lc_ctype, user_enc) ||
        !check_locale_encoding(lc_collate, user_enc))
        exit(1);                /* check_locale_encoding printed the error */

}

void setup_pgdata ( void   ) 

Definition at line 2866 of file initdb.c.

References _, canonicalize_path(), pg_data, pg_malloc(), pg_strdup(), pgdata_native, progname, and putenv.

Referenced by main().

{
    char       *pgdata_get_env, *pgdata_set_env;

    if (strlen(pg_data) == 0)
    {
        pgdata_get_env = getenv("PGDATA");
        if (pgdata_get_env && strlen(pgdata_get_env))
        {
            /* PGDATA found */
            pg_data = pg_strdup(pgdata_get_env);
        }
        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"),
                    progname);
            exit(1);
        }
    }

    pgdata_native = pg_strdup(pg_data);
    canonicalize_path(pg_data);

    /*
     * we have to set PGDATA for postgres rather than pass it on the command
     * line to avoid dumb quoting problems on Windows, and we would especially
     * need quotes otherwise on Windows because paths there are most likely to
     * have embedded spaces.
     */
    pgdata_set_env = pg_malloc(8 + strlen(pg_data));
    sprintf(pgdata_set_env, "PGDATA=%s", pg_data);
    putenv(pgdata_set_env);
}

static void setup_privileges ( void   )  [static]

Definition at line 2044 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, escape_quotes(), NULL, PG_CMD_PUTS, replace_token(), snprintf(), and username.

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char      **priv_lines;
    static char *privileges_setup[] = {
        "UPDATE pg_class "
        "  SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' "
        "  WHERE relkind IN ('r', 'v', 'm', 'S') AND relacl IS NULL;\n",
        "GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n",
        "GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n",
        "REVOKE ALL ON pg_largeobject FROM PUBLIC;\n",
        NULL
    };

    fputs(_("setting privileges on built-in objects ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
                               escape_quotes(username));
    for (line = priv_lines; *line != NULL; line++)
        PG_CMD_PUTS(*line);

    PG_CMD_CLOSE;

    check_ok();
}

static void setup_schema ( void   )  [static]

Definition at line 2111 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, escape_quotes(), features_file, free, info_schema_file, infoversion, PG_CMD_PRINTF1, PG_CMD_PUTS, readfile(), and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char      **lines;

    fputs(_("creating information schema ... "), stdout);
    fflush(stdout);

    lines = readfile(info_schema_file);

    /*
     * We use -j here to avoid backslashing stuff in information_schema.sql
     */
    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s -j template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = lines; *line != NULL; line++)
    {
        PG_CMD_PUTS(*line);
        free(*line);
    }

    free(lines);

    PG_CMD_CLOSE;

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info "
                   "  SET character_value = '%s' "
                   "  WHERE implementation_info_name = 'DBMS VERSION';\n",
                   infoversion);

    PG_CMD_PRINTF1("COPY information_schema.sql_features "
                   "  (feature_id, feature_name, sub_feature_id, "
                   "  sub_feature_name, is_supported, comments) "
                   " FROM E'%s';\n",
                   escape_quotes(features_file));

    PG_CMD_CLOSE;

    check_ok();
}

void setup_signals ( void   ) 

Definition at line 3126 of file initdb.c.

References pqsignal(), SIG_IGN, SIGHUP, SIGPIPE, SIGQUIT, and trapsig().

Referenced by initialize_data_directory().

{
    /* some of these are not valid on Windows */
#ifdef SIGHUP
    pqsignal(SIGHUP, trapsig);
#endif
#ifdef SIGINT
    pqsignal(SIGINT, trapsig);
#endif
#ifdef SIGQUIT
    pqsignal(SIGQUIT, trapsig);
#endif
#ifdef SIGTERM
    pqsignal(SIGTERM, trapsig);
#endif

    /* Ignore SIGPIPE when writing to backend, so we can clean up */
#ifdef SIGPIPE
    pqsignal(SIGPIPE, SIG_IGN);
#endif
}

static void setup_sysviews ( void   )  [static]

Definition at line 1682 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, free, PG_CMD_PUTS, readfile(), snprintf(), and system_views_file.

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;
    char      **line;
    char      **sysviews_setup;

    fputs(_("creating system views ... "), stdout);
    fflush(stdout);

    sysviews_setup = readfile(system_views_file);

    /*
     * We use -j here to avoid backslashing stuff in system_views.sql
     */
    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s -j template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    for (line = sysviews_setup; *line != NULL; line++)
    {
        PG_CMD_PUTS(*line);
        free(*line);
    }

    PG_CMD_CLOSE;

    free(sysviews_setup);

    check_ok();
}

void setup_text_search ( void   ) 

Definition at line 3091 of file initdb.c.

References _, default_text_search_config, find_matching_ts_config(), lc_ctype, NULL, and progname.

Referenced by main().

{
    if (strlen(default_text_search_config) == 0)
    {
        default_text_search_config = find_matching_ts_config(lc_ctype);
        if (default_text_search_config == NULL)
        {
            printf(_("%s: could not find suitable text search configuration for locale \"%s\"\n"),
                   progname, lc_ctype);
            default_text_search_config = "simple";
        }
    }
    else
    {
        const char *checkmatch = find_matching_ts_config(lc_ctype);

        if (checkmatch == NULL)
        {
            printf(_("%s: warning: suitable text search configuration for locale \"%s\" is unknown\n"),
                   progname, lc_ctype);
        }
        else if (strcmp(checkmatch, default_text_search_config) != 0)
        {
            printf(_("%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n"),
                   progname, default_text_search_config, lc_ctype);
        }
    }

    printf(_("The default text search configuration will be set to \"%s\".\n"),
           default_text_search_config);

}

static void test_config_settings ( void   )  [static]

Definition at line 1084 of file initdb.c.

References _, backend_exec, boot_options, DEVNULL, i, MIN_BUFS_FOR_CONNS, n_buffers, n_connections, snprintf(), system(), and SYSTEMQUOTE.

Referenced by initialize_data_directory().

{
    /*
     * This macro defines the minimum shared_buffers we want for a given
     * max_connections value. The arrays show the settings to try.
     */
#define MIN_BUFS_FOR_CONNS(nconns)  ((nconns) * 10)

    static const int trial_conns[] = {
        100, 50, 40, 30, 20, 10
    };
    static const int trial_bufs[] = {
        16384, 8192, 4096, 3584, 3072, 2560, 2048, 1536,
        1000, 900, 800, 700, 600, 500,
        400, 300, 200, 100, 50
    };

    char        cmd[MAXPGPATH];
    const int   connslen = sizeof(trial_conns) / sizeof(int);
    const int   bufslen = sizeof(trial_bufs) / sizeof(int);
    int         i,
                status,
                test_conns,
                test_buffs,
                ok_buffers = 0;


    printf(_("selecting default max_connections ... "));
    fflush(stdout);

    for (i = 0; i < connslen; i++)
    {
        test_conns = trial_conns[i];
        test_buffs = MIN_BUFS_FOR_CONNS(test_conns);

        snprintf(cmd, sizeof(cmd),
                 SYSTEMQUOTE "\"%s\" --boot -x0 %s "
                 "-c max_connections=%d "
                 "-c shared_buffers=%d "
                 "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
                 backend_exec, boot_options,
                 test_conns, test_buffs,
                 DEVNULL, DEVNULL);
        status = system(cmd);
        if (status == 0)
        {
            ok_buffers = test_buffs;
            break;
        }
    }
    if (i >= connslen)
        i = connslen - 1;
    n_connections = trial_conns[i];

    printf("%d\n", n_connections);

    printf(_("selecting default shared_buffers ... "));
    fflush(stdout);

    for (i = 0; i < bufslen; i++)
    {
        /* Use same amount of memory, independent of BLCKSZ */
        test_buffs = (trial_bufs[i] * 8192) / BLCKSZ;
        if (test_buffs <= ok_buffers)
        {
            test_buffs = ok_buffers;
            break;
        }

        snprintf(cmd, sizeof(cmd),
                 SYSTEMQUOTE "\"%s\" --boot -x0 %s "
                 "-c max_connections=%d "
                 "-c shared_buffers=%d "
                 "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
                 backend_exec, boot_options,
                 n_connections, test_buffs,
                 DEVNULL, DEVNULL);
        status = system(cmd);
        if (status == 0)
            break;
    }
    n_buffers = test_buffs;

    if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
        printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024);
    else
        printf("%dkB\n", n_buffers * (BLCKSZ / 1024));
}

static void trapsig ( int  signum  )  [static]

Definition at line 2369 of file initdb.c.

References caught_signal, and pqsignal().

Referenced by setup_signals().

{
    /* handle systems that reset the handler, like Windows (grr) */
    pqsignal(signum, trapsig);
    caught_signal = true;
}

static void usage ( const char *  progname  )  [static]

Definition at line 2729 of file initdb.c.

References _.

{
    printf(_("%s initializes a PostgreSQL database cluster.\n\n"), progname);
    printf(_("Usage:\n"));
    printf(_("  %s [OPTION]... [DATADIR]\n"), progname);
    printf(_("\nOptions:\n"));
    printf(_("  -A, --auth=METHOD         default authentication method for local connections\n"));
    printf(_("      --auth-host=METHOD    default authentication method for local TCP/IP connections\n"));
    printf(_("      --auth-local=METHOD   default authentication method for local-socket connections\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       set default locale for new databases\n"));
    printf(_("      --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n"
             "      --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n"
             "                            set default locale in the respective category for\n"
             "                            new databases (default taken from environment)\n"));
    printf(_("      --no-locale           equivalent to --locale=C\n"));
    printf(_("      --pwfile=FILE         read password for the new superuser from file\n"));
    printf(_("  -T, --text-search-config=CFG\n"
         "                            default text search configuration\n"));
    printf(_("  -U, --username=NAME       database superuser name\n"));
    printf(_("  -W, --pwprompt            prompt for a password for the new superuser\n"));
    printf(_("  -X, --xlogdir=XLOGDIR     location for the transaction log directory\n"));
    printf(_("\nLess commonly used options:\n"));
    printf(_("  -d, --debug               generate lots of debugging output\n"));
    printf(_("  -k, --data-checksums      use data page checksums\n"));
    printf(_("  -L DIRECTORY              where to find the input files\n"));
    printf(_("  -n, --noclean             do not clean up after errors\n"));
    printf(_("  -N, --nosync              do not wait for changes to be written safely to disk\n"));
    printf(_("  -s, --show                show internal settings\n"));
    printf(_("  -S, --sync-only           only sync data directory\n"));
    printf(_("\nOther options:\n"));
    printf(_("  -V, --version             output version information, then exit\n"));
    printf(_("  -?, --help                show this help, then exit\n"));
    printf(_("\nIf the data directory is not specified, the environment variable PGDATA\n"
             "is used.\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
}

static void vacuum_db ( void   )  [static]

Definition at line 2194 of file initdb.c.

References _, backend_exec, backend_options, check_ok(), DEVNULL, PG_CMD_PUTS, and snprintf().

Referenced by initialize_data_directory().

{
    PG_CMD_DECL;

    fputs(_("vacuuming database template1 ... "), stdout);
    fflush(stdout);

    snprintf(cmd, sizeof(cmd),
             "\"%s\" %s template1 >%s",
             backend_exec, backend_options,
             DEVNULL);

    PG_CMD_OPEN;

    PG_CMD_PUTS("ANALYZE;\nVACUUM FULL;\nVACUUM FREEZE;\n");

    PG_CMD_CLOSE;

    check_ok();
}

static void walkdir ( char *  path,
void(*)(char *fname, bool isdir)  action 
) [static]

Definition at line 521 of file initdb.c.

References _, closedir(), dirent::d_name, exit_nicely, lstat, MAXPGPATH, NULL, opendir(), progname, readdir(), snprintf(), strerror(), and subpath().

Referenced by perform_fsync().

{
    DIR        *dir;
    struct dirent *direntry;
    char        subpath[MAXPGPATH];

    dir = opendir(path);
    if (dir == NULL)
    {
        fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }

    while (errno = 0, (direntry = readdir(dir)) != NULL)
    {
        struct stat fst;

        if (strcmp(direntry->d_name, ".") == 0 ||
            strcmp(direntry->d_name, "..") == 0)
            continue;

        snprintf(subpath, MAXPGPATH, "%s/%s", path, direntry->d_name);

        if (lstat(subpath, &fst) < 0)
        {
            fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
                    progname, subpath, strerror(errno));
            exit_nicely();
        }

        if (S_ISDIR(fst.st_mode))
            walkdir(subpath, action);
        else if (S_ISREG(fst.st_mode))
            (*action) (subpath, false);
    }

#ifdef WIN32
    /*
     * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
     * released version
     */
    if (GetLastError() == ERROR_NO_MORE_FILES)
        errno = 0;
#endif

    if (errno)
    {
        fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }

    closedir(dir);

    /*
     * It's important to fsync the destination directory itself as individual
     * file fsyncs don't guarantee that the directory entry for the file is
     * synced.  Recent versions of ext4 have made the window much wider but
     * it's been an issue for ext3 and other filesystems in the past.
     */
    (*action) (path, true);
}

void warn_on_mount_point ( int  error  ) 

Definition at line 3313 of file initdb.c.

References _.

Referenced by create_data_directory(), and create_xlog_symlink().

{
    if (error == 2)
        fprintf(stderr,
                _("It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n"));
    else if (error == 3)
        fprintf(stderr,
                _("It contains a lost+found directory, perhaps due to it being a mount point.\n"));

    fprintf(stderr,
            _("Using a mount point directly as the data directory is not recommended.\n"
              "Create a subdirectory under the mount point.\n"));
}

static void write_version_file ( char *  extrapath  )  [static]

Definition at line 1016 of file initdb.c.

References _, exit_nicely, free, NULL, PG_BINARY_W, pg_data, pg_malloc(), progname, and strerror().

Referenced by initialize_data_directory().

{
    FILE       *version_file;
    char       *path;

    if (extrapath == NULL)
    {
        path = pg_malloc(strlen(pg_data) + 12);
        sprintf(path, "%s/PG_VERSION", pg_data);
    }
    else
    {
        path = pg_malloc(strlen(pg_data) + strlen(extrapath) + 13);
        sprintf(path, "%s/%s/PG_VERSION", pg_data, extrapath);
    }

    if ((version_file = fopen(path, PG_BINARY_W)) == NULL)
    {
        fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    if (fprintf(version_file, "%s\n", PG_MAJORVERSION) < 0 ||
        fclose(version_file))
    {
        fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    free(path);
}

static void writefile ( char *  path,
char **  lines 
) [static]

Definition at line 485 of file initdb.c.

References _, exit_nicely, free, NULL, progname, and strerror().

Referenced by setup_config().

{
    FILE       *out_file;
    char      **line;

    if ((out_file = fopen(path, "w")) == NULL)
    {
        fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    for (line = lines; *line != NULL; line++)
    {
        if (fputs(*line, out_file) < 0)
        {
            fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
                    progname, path, strerror(errno));
            exit_nicely();
        }
        free(*line);
    }
    if (fclose(out_file))
    {
        fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
                progname, path, strerror(errno));
        exit_nicely();
    }
}


Variable Documentation

const char* auth_methods_host[] [static]
Initial value:
 {"trust", "reject", "md5", "password", "ident", "radius",


















NULL}

Definition at line 67 of file initdb.c.

Referenced by main().

const char* auth_methods_local[] [static]
Initial value:
 {"trust", "reject", "md5", "password", "peer", "radius",






NULL}

Definition at line 87 of file initdb.c.

Referenced by main().

const char* authmethodhost = "" [static]

Definition at line 115 of file initdb.c.

Referenced by main(), and setup_config().

const char* authmethodlocal = "" [static]

Definition at line 116 of file initdb.c.

Referenced by main(), and setup_config().

char* authwarning = NULL [static]

Definition at line 162 of file initdb.c.

Referenced by check_authmethod_unspecified(), and main().

char backend_exec[MAXPGPATH] [static]
const char* backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true" [static]
char bin_path[MAXPGPATH] [static]

Definition at line 201 of file initdb.c.

Referenced by setup_bin_paths(), and setup_data_file_paths().

char* bki_file [static]

Definition at line 129 of file initdb.c.

Referenced by bootstrap_template1(), and setup_data_file_paths().

const char* boot_options = "-F" [static]

Definition at line 174 of file initdb.c.

Referenced by bootstrap_template1(), and test_config_settings().

bool caught_signal = false [static]

Definition at line 145 of file initdb.c.

Referenced by check_ok(), and trapsig().

char* conf_file [static]

Definition at line 134 of file initdb.c.

Referenced by set_null_conf(), setup_config(), and setup_data_file_paths().

char* conversion_file [static]

Definition at line 135 of file initdb.c.

Referenced by setup_conversion(), and setup_data_file_paths().

bool data_checksums = false [static]

Definition at line 122 of file initdb.c.

Referenced by bootstrap_template1(), and main().

bool debug = false [static]

Definition at line 117 of file initdb.c.

const char* default_text_search_config = "" [static]

Definition at line 111 of file initdb.c.

Referenced by main(), setup_config(), and setup_text_search().

char* desc_file [static]

Definition at line 130 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_description().

char* dictionary_file [static]

Definition at line 136 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_dictionary().

bool do_sync = true [static]

Definition at line 119 of file initdb.c.

Referenced by main().

char* encoding = "" [static]
char* encodingid = "0" [static]

Definition at line 128 of file initdb.c.

Referenced by bootstrap_template1(), and setup_locale_encoding().

char* features_file [static]

Definition at line 138 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_schema().

bool found_existing_pgdata = false [static]

Definition at line 141 of file initdb.c.

Referenced by create_data_directory(), and exit_nicely().

bool found_existing_xlogdir = false [static]

Definition at line 143 of file initdb.c.

Referenced by create_xlog_symlink(), and exit_nicely().

char* hba_file [static]

Definition at line 132 of file initdb.c.

Referenced by setup_config(), and setup_data_file_paths().

char* ident_file [static]

Definition at line 133 of file initdb.c.

Referenced by setup_config(), and setup_data_file_paths().

char* info_schema_file [static]

Definition at line 137 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_schema().

char infoversion[100] [static]

Definition at line 144 of file initdb.c.

Referenced by set_info_version(), and setup_schema().

char* lc_collate = "" [static]
char* lc_ctype = "" [static]
char* lc_messages = "" [static]

Definition at line 110 of file initdb.c.

Referenced by get_control_data(), main(), setlocales(), setup_config(), and setup_locale_encoding().

char* lc_monetary = "" [static]

Definition at line 107 of file initdb.c.

Referenced by get_control_data(), main(), setlocales(), setup_config(), and setup_locale_encoding().

char* lc_numeric = "" [static]

Definition at line 108 of file initdb.c.

Referenced by get_control_data(), main(), setlocales(), setup_config(), and setup_locale_encoding().

char* lc_time = "" [static]

Definition at line 109 of file initdb.c.

Referenced by get_control_data(), main(), setlocales(), setup_config(), and setup_locale_encoding().

char* locale = "" [static]

Definition at line 104 of file initdb.c.

Referenced by Generic_Text_IC_like(), like_fixed_prefix(), main(), and setlocales().

bool made_new_pgdata = false [static]

Definition at line 140 of file initdb.c.

Referenced by create_data_directory(), and exit_nicely().

bool made_new_xlogdir = false [static]

Definition at line 142 of file initdb.c.

Referenced by create_xlog_symlink(), and exit_nicely().

int n_buffers = 50 [static]

Definition at line 152 of file initdb.c.

Referenced by setup_config(), and test_config_settings().

int n_connections = 10 [static]

Definition at line 151 of file initdb.c.

Referenced by setup_config(), and test_config_settings().

bool noclean = false [static]

Definition at line 118 of file initdb.c.

Referenced by exit_nicely(), and main().

int output_errno = 0 [static]

Definition at line 147 of file initdb.c.

Referenced by check_ok().

bool output_failed = false [static]

Definition at line 146 of file initdb.c.

Referenced by check_ok().

char* pg_data = "" [static]
char* pgdata_native [static]

Definition at line 148 of file initdb.c.

Referenced by main(), and setup_pgdata().

const char* progname [static]

Definition at line 127 of file initdb.c.

char* pwfilename = NULL [static]

Definition at line 114 of file initdb.c.

Referenced by check_need_password(), get_set_pwd(), initialize_data_directory(), and main().

bool pwprompt = false [static]

Definition at line 113 of file initdb.c.

Referenced by check_need_password(), get_set_pwd(), initialize_data_directory(), and main().

char* share_path = NULL [static]
char* shdesc_file [static]

Definition at line 131 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_description().

bool show_setting = false [static]

Definition at line 121 of file initdb.c.

Referenced by main(), and setup_data_file_paths().

const char* subdirs[]
Initial value:
 {
    "global",
    "pg_xlog",
    "pg_xlog/archive_status",
    "pg_clog",
    "pg_notify",
    "pg_serial",
    "pg_snapshots",
    "pg_subtrans",
    "pg_twophase",
    "pg_multixact/members",
    "pg_multixact/offsets",
    "base",
    "base/1",
    "pg_tblspc",
    "pg_stat",
    "pg_stat_tmp"
}

Definition at line 180 of file initdb.c.

Referenced by initialize_data_directory().

bool sync_only = false [static]

Definition at line 120 of file initdb.c.

Referenced by main().

char* system_views_file [static]

Definition at line 139 of file initdb.c.

Referenced by setup_data_file_paths(), and setup_sysviews().

Definition at line 852 of file initdb.c.

char* username = "" [static]
char* xlog_dir = "" [static]

Definition at line 123 of file initdb.c.

Referenced by create_xlog_symlink(), exit_nicely(), and main().