*** /laptop/initdb.c Sat Nov 8 00:10:58 2003 --- initdb.c Fri Nov 7 23:55:07 2003 *************** *** 1,4 **** - /*------------------------------------------------------------------------- * * initdb --- 1,3 ---- *************** *** 53,59 **** char *datadir = PGDATADIR; /* values to be obtained from arguments */ - char *pg_data = ""; char *encoding = ""; char *locale = ""; --- 52,57 ---- *************** *** 93,100 **** bool not_ok = false; /* defaults */ - int n_buffers = 50; int n_connections = 10; /* platform specific path stuff */ --- 91,98 ---- bool not_ok = false; /* defaults */ int n_connections = 10; + int n_buffers = 50; /* platform specific path stuff */ *************** *** 104,116 **** #else #define EXE "" #define DEVNULL "/dev/null" ! #endif /* defined(__CYGWIN__) || defined(WIN32) */ #ifdef WIN32 #define PATHSEP ';' #else #define PATHSEP ':' ! #endif /* WIN32 */ /* detected path to postgres and (we assume) friends */ char *pgpath; --- 102,114 ---- #else #define EXE "" #define DEVNULL "/dev/null" ! #endif #ifdef WIN32 #define PATHSEP ';' #else #define PATHSEP ':' ! #endif /* detected path to postgres and (we assume) friends */ char *pgpath; *************** *** 122,140 **** #ifdef WIN32 static char *expanded_path(char *); - static int init_unlink(const char *); - #else ! #define expanded_path(x) ( x ) ! #define init_unlink(x) unlink( (x) ) ! #endif /* WIN32 */ static char **readfile(char *); static void writefile(char *, char **); static char *get_id(void); static char *get_encoding_id(char *); static char *get_short_version(void); ! static int build_path(char *, mode_t); static bool check_data_dir(void); static bool mkdatadir(char *); static bool chklocale(const char *); --- 120,135 ---- #ifdef WIN32 static char *expanded_path(char *); #else ! #define expanded_path(x) (x) ! #endif static char **readfile(char *); static void writefile(char *, char **); static char *get_id(void); static char *get_encoding_id(char *); static char *get_short_version(void); ! static int mkdir_p(char *, mode_t); static bool check_data_dir(void); static bool mkdatadir(char *); static bool chklocale(const char *); *************** *** 151,157 **** static void setup_config(void); static void bootstrap_template1(char *); static void setup_shadow(void); ! static void get_set_pw(void); static void unlimit_systables(void); static void setup_depend(void); static void setup_sysviews(void); --- 146,152 ---- static void setup_config(void); static void bootstrap_template1(char *); static void setup_shadow(void); ! static void get_set_pwd(void); static void unlimit_systables(void); static void setup_depend(void); static void setup_sysviews(void); *************** *** 171,230 **** /* * macros for running pipes to postgres */ - #define PG_CMD_DECL char cmd[MAXPGPATH]; char ** line ; FILE * pg #define PG_CMD_DECL_NOLINE char cmd[MAXPGPATH]; FILE * pg - #define PG_CMD_OPEN \ - do {\ - pg = popen(cmd,PG_BINARY_W);\ - if (pg == NULL) \ - exit_nicely();\ - } while (0) - #define PG_CMD_CLOSE \ - do {\ - if(pclose(pg)>>8 &0xff)\ - exit_nicely();\ - } while (0) - #define PG_CMD_PUTLINE \ - do {\ - if (fputs(*line, pg) < 0) \ - exit_nicely(); \ - fflush(pg);\ - } while (0) - - ! #ifdef WIN32 ! ! /* workaround for win32 unlink bug, not using logging like in port/dirmod.c */ ! ! /* make sure we call the real unlink from MSVCRT */ ! #ifdef unlink ! #undef unlink #endif - static int - init_unlink(const char *path) - { - while (unlink(path)) - { - if (errno != EACCES) - return -1; - Sleep(100); /* ms */ - } - return 0; - } - #endif /* WIN32 */ - /* ! * routines to check mem allocations and fail noisily * Note that we can't call exit_nicely() on a memory failure, as it calls * rmtree() which needs memory allocation. So we just exit with a bang. * */ - static void * xmalloc(size_t size) { --- 166,206 ---- /* * macros for running pipes to postgres */ #define PG_CMD_DECL char cmd[MAXPGPATH]; char ** line ; FILE * pg #define PG_CMD_DECL_NOLINE char cmd[MAXPGPATH]; FILE * pg + #define PG_CMD_OPEN \ + do { \ + pg = popen(cmd,PG_BINARY_W); \ + if (pg == NULL) \ + exit_nicely(); \ + } while (0) + + #define PG_CMD_CLOSE \ + do { \ + if(pclose(pg) >> 8 & 0xff) \ + exit_nicely(); \ + } while (0) ! #define PG_CMD_PUTLINE \ ! do { \ ! if (fputs(*line, pg) < 0) \ ! exit_nicely(); \ ! fflush(pg); \ ! } while (0) ! #ifndef WIN32 ! #define QUOTE_PATH "" ! #else ! #define QUOTE_PATH "\"" #endif /* ! * routines to check mem allocations and fail noisily. * Note that we can't call exit_nicely() on a memory failure, as it calls * rmtree() which needs memory allocation. So we just exit with a bang. * */ static void * xmalloc(size_t size) { *************** *** 263,344 **** static bool rmtree(char *path, bool rmtopdir) { ! char filepath[MAXPGPATH]; ! DIR *dir; ! struct dirent *file; ! char **filenames; ! char **filename; ! int numnames = 0; ! struct stat statbuf; ! /* ! * we copy all the names out of the directory before we start ! * modifying it. ! * ! */ ! ! dir = opendir(path); ! if (dir == NULL) ! return false; ! ! while ((file = readdir(dir)) != NULL) ! { ! if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) ! numnames++; ! } ! ! rewinddir(dir); ! ! filenames = xmalloc((numnames + 2) * sizeof(char *)); ! numnames = 0; ! ! while ((file = readdir(dir)) != NULL) ! { ! if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) ! filenames[numnames++] = xstrdup(file->d_name); ! } ! ! filenames[numnames] = NULL; ! ! closedir(dir); ! ! /* now we have the names we can start removing things */ ! ! for (filename = filenames; *filename; filename++) ! { ! snprintf(filepath, MAXPGPATH, "%s/%s", path, *filename); ! ! if (stat(filepath, &statbuf) != 0) ! return false; ! ! if (S_ISDIR(statbuf.st_mode)) ! { ! /* call ourselves recursively for a directory */ ! if (!rmtree(filepath, true)) ! return false; ! } ! else ! { ! if (init_unlink(filepath) != 0) ! return false; ! } ! } ! if (rmtopdir) ! { ! if (rmdir(path) != 0) ! return false; ! } ! return true; } /* * make all paths look like unix, with forward slashes * also strip any trailing slash */ - static void canonicalise_path(char *path) { --- 239,271 ---- static bool rmtree(char *path, bool rmtopdir) { ! char buf[MAXPGPATH + 64]; ! int ret = 1; ! #ifndef WIN32 ! /* doesn't handle .* files */ ! snprintf(buf, sizeof(buf), "rm -rf '%s%s'", path, ! (rmtopdir) ? "" : "/*"); ! #else ! snprintf(buf, sizeof(buf), "rmdir /s /q \"%s\"", path); ! #endif ! if (system(buf) != 0) ! ret = 0; ! #ifdef WIN32 ! if (ret == 1 && !rmtopdir) ! ret = !mkdir(path); /* recreate, no permission issues? */ ! #endif ! return ret; } /* * make all paths look like unix, with forward slashes * also strip any trailing slash + * needed? */ static void canonicalise_path(char *path) { *************** *** 349,355 **** #ifdef WIN32 if (*p == '\\') *p = '/'; ! #endif /* WIN32 */ } if (p != path && *--p == '/') *p = '\0'; --- 276,282 ---- #ifdef WIN32 if (*p == '\\') *p = '/'; ! #endif } if (p != path && *--p == '/') *p = '\0'; *************** *** 361,367 **** * This does most of what sed was used for in the shell script, but * doesn't need any regexp stuff. */ - static char ** replace_token(char **lines, char *token, char *replacement) { --- 288,293 ---- *************** *** 372,378 **** replen, diff; - for (i = 0; lines[i]; i++) numlines++; --- 298,303 ---- *************** *** 431,439 **** char *buffer; int c; ! infile = fopen(path, "r"); ! ! if (!infile) { fprintf(stderr, "could not read %s ... ", path); exit_nicely(); --- 356,362 ---- char *buffer; int c; ! if ((infile = fopen(path, "r")) == NULL) { fprintf(stderr, "could not read %s ... ", path); exit_nicely(); *************** *** 491,498 **** FILE *out_file; char **line; ! out_file = fopen(path, PG_BINARY_W); ! if (out_file == NULL) { fprintf(stderr, "could not write %s ... ", path); exit_nicely(); --- 414,421 ---- FILE *out_file; char **line; ! ; ! if ((out_file = fopen(path, PG_BINARY_W)) == NULL) { fprintf(stderr, "could not write %s ... ", path); exit_nicely(); *************** *** 515,523 **** * we also assume it isn't null. * */ - static int ! build_path(char *path, mode_t omode) { struct stat sb; mode_t numask, --- 438,445 ---- * we also assume it isn't null. * */ static int ! mkdir_p(char *path, mode_t omode) { struct stat sb; mode_t numask, *************** *** 532,538 **** retval = 0; #ifdef WIN32 - /* skip network and drive specifiers for win32 */ if (strlen(p) >= 2) { --- 454,459 ---- *************** *** 551,557 **** p += 2; } } ! #endif /* WIN32 */ if (p[0] == '/') /* Skip leading '/'. */ ++p; --- 472,478 ---- p += 2; } } ! #endif if (p[0] == '/') /* Skip leading '/'. */ ++p; *************** *** 614,620 **** } if (!first && !last) (void) umask(oumask); ! return (retval); } /* --- 535,541 ---- } if (!first && !last) (void) umask(oumask); ! return retval; } /* *************** *** 673,679 **** progname); exit(1); } ! #endif /* __BEOS__ */ #else /* the windows code */ --- 594,600 ---- progname); exit(1); } ! #endif #else /* the windows code */ *************** *** 687,693 **** pw->pw_uid = 1; GetUserName(pw->pw_name, &pwname_size); ! #endif /* ! WIN32 */ return xstrdup(pw->pw_name); } --- 608,614 ---- pw->pw_uid = 1; GetUserName(pw->pw_name, &pwname_size); ! #endif return xstrdup(pw->pw_name); } *************** *** 785,791 **** closedir(chkdir); ! return (empty); } /* --- 706,712 ---- closedir(chkdir); ! return empty; } /* *************** *** 812,818 **** else if (subdir == NULL || errno != ENOENT) return false; else ! return !build_path(path, 0700); } --- 733,739 ---- else if (subdir == NULL || errno != ENOENT) return false; else ! return !mkdir_p(path, 0700); } *************** *** 853,859 **** * don't overkill * */ - #define FIND_SUCCESS 0 #define FIND_NOT_FOUND 1 #define FIND_STAT_ERR 2 --- 774,779 ---- *************** *** 875,885 **** char line[100]; #ifndef WIN32 - int permmask = S_IROTH | S_IXOTH; #endif - struct stat statbuf; FILE *pgver; int plen = strlen(path); --- 795,803 ---- *************** *** 900,911 **** return FIND_NOT_REGFILE; #ifndef WIN32 ! ! /* on windows a .exe file should be executable - this is the unix test */ ! if ((statbuf.st_mode & permmask) != permmask) return FIND_BAD_PERM; ! #endif /* ! WIN32 */ snprintf(cmd, MAXPGPATH, "\"%s/postgres\" -V 2>%s", path, DEVNULL); --- 818,830 ---- return FIND_NOT_REGFILE; #ifndef WIN32 ! /* ! * Only unix requires this test, on WIN32 an .exe file should be ! * executable ! */ if ((statbuf.st_mode & permmask) != permmask) return FIND_BAD_PERM; ! #endif snprintf(cmd, MAXPGPATH, "\"%s/postgres\" -V 2>%s", path, DEVNULL); *************** *** 913,923 **** return FIND_EXEC_ERR; if (fgets(line, sizeof(line), pgver) == NULL) - { perror("fgets failure"); - } - pclose(pgver); if (strcmp(line, PG_VERSIONSTR) != 0) --- 832,839 ---- *************** *** 926,939 **** return FIND_SUCCESS; } - #ifdef WIN32 - /* * Windows doesn't like relative paths to executables (other things work fine) * so we call its builtin function to expand them. Elsewhere this is a NOOP * */ ! static char * expanded_path(char *path) { --- 842,853 ---- return FIND_SUCCESS; } /* * Windows doesn't like relative paths to executables (other things work fine) * so we call its builtin function to expand them. Elsewhere this is a NOOP * */ ! #ifdef WIN32 static char * expanded_path(char *path) { *************** *** 947,953 **** canonicalise_path(abspath); return xstrdup(abspath); } ! #endif /* WIN32 */ /* * set the paths pointing to postgres --- 861,867 ---- canonicalise_path(abspath); return xstrdup(abspath); } ! #endif /* * set the paths pointing to postgres *************** *** 1078,1140 **** } /* ! * check how many buffers we can run with * */ static void ! test_buffers(void) { char *format = ! "\"%s/postgres\" -boot -x 0 -F " ! "-c shared_buffers=%d -c max_connections=5 template1 <%s >%s 2>&1"; char cmd[MAXPGPATH]; ! int bufs[] = ! {1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 50}; ! int len = sizeof(bufs) / sizeof(int); int i, status; for (i = 0; i < len; i++) { ! snprintf(cmd, sizeof(cmd), format, pgpath, bufs[i], DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; ! n_buffers = bufs[i]; ! printf("buffers set to %d\n", n_buffers); } /* ! * check how many connections we can sustain * */ static void ! test_connections(void) { char *format = ! "\"%s/postgres\" -boot -x 0 -F " "-c shared_buffers=%d -c max_connections=%d template1 <%s >%s 2>&1"; char cmd[MAXPGPATH]; ! int conns[] = {100, 50, 40, 30, 20, 10}; ! int len = sizeof(conns) / sizeof(int); int i, status; for (i = 0; i < len; i++) { ! snprintf(cmd, sizeof(cmd), format, ! pgpath, n_buffers, conns[i], DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; ! n_connections = conns[i]; ! printf("connections set to %d\n", n_connections); } /* --- 992,1054 ---- } /* ! * check how many connections we can sustain * */ static void ! test_connections(void) { char *format = ! "\"%s/postgres\" -boot -x 0 -F " ! "-c shared_buffers=%d -c max_connections=%d template1 <%s >%s 2>&1"; char cmd[MAXPGPATH]; ! int conns[] = {100, 50, 40, 30, 20, 10}; ! int len = sizeof(conns) / sizeof(int); int i, status; for (i = 0; i < len; i++) { ! snprintf(cmd, sizeof(cmd), format, ! pgpath, conns[i] * 5, conns[i], DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; ! n_connections = conns[i]; ! printf("connections set to %d\n", n_connections); } /* ! * check how many buffers we can run with * */ static void ! test_buffers(void) { char *format = ! "\"%s/postgres\" -boot -x 0 -F " "-c shared_buffers=%d -c max_connections=%d template1 <%s >%s 2>&1"; char cmd[MAXPGPATH]; ! int bufs[] = {1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 50}; ! int len = sizeof(bufs) / sizeof(int); int i, status; for (i = 0; i < len; i++) { ! snprintf(cmd, sizeof(cmd), format, pgpath, bufs[i], n_connections, ! DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; ! n_buffers = bufs[i]; ! printf("buffers set to %d\n", n_buffers); } /* *************** *** 1155,1166 **** conflines = readfile(conf_file); - snprintf(repltok, sizeof(repltok), "shared_buffers = %d", n_buffers); - conflines = replace_token(conflines, "#shared_buffers = 1000", repltok); - snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections); conflines = replace_token(conflines, "#max_connections = 100", repltok); snprintf(repltok, sizeof(repltok), "lc_messages = '%s'", lc_messages); conflines = replace_token(conflines, "#lc_messages = 'C'", repltok); --- 1069,1080 ---- conflines = readfile(conf_file); snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections); conflines = replace_token(conflines, "#max_connections = 100", repltok); + snprintf(repltok, sizeof(repltok), "shared_buffers = %d", n_buffers); + conflines = replace_token(conflines, "#shared_buffers = 1000", repltok); + snprintf(repltok, sizeof(repltok), "lc_messages = '%s'", lc_messages); conflines = replace_token(conflines, "#lc_messages = 'C'", repltok); *************** *** 1190,1196 **** conflines = replace_token(conflines, "host all all ::1", "#host all all ::1"); ! #endif /* ! HAVE_IPV6 */ snprintf(path, MAXPGPATH, "%s/pg_hba.conf", pg_data); --- 1104,1110 ---- conflines = replace_token(conflines, "host all all ::1", "#host all all ::1"); ! #endif snprintf(path, MAXPGPATH, "%s/pg_hba.conf", pg_data); *************** *** 1211,1217 **** free(conflines); check_ok(); - } --- 1125,1130 ---- *************** *** 1258,1264 **** * already called setlocale(). * */ - snprintf(cmd, MAXPGPATH, "LC_COLLATE=%s", lc_collate); putenv(xstrdup(cmd)); --- 1171,1176 ---- *************** *** 1337,1359 **** * */ static void ! get_set_pw(void) { PG_CMD_DECL_NOLINE; ! char *pw1, ! *pw2; ! char pwpath[MAXPGPATH]; struct stat statbuf; ! pw1 = simple_prompt("Enter new superuser password: ", 100, false); ! pw2 = simple_prompt("Enter it again: ", 100, false); ! if (strcmp(pw1, pw2) != 0) { fprintf(stderr, "Passwords didn't match.\n"); exit_nicely(); } ! free(pw2); printf("storing the password ... "); --- 1249,1271 ---- * */ static void ! get_set_pwd(void) { PG_CMD_DECL_NOLINE; ! char *pwd1, ! *pwd2; ! char pwdpath[MAXPGPATH]; struct stat statbuf; ! pwd1 = simple_prompt("Enter new superuser password: ", 100, false); ! pwd2 = simple_prompt("Enter it again: ", 100, false); ! if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, "Passwords didn't match.\n"); exit_nicely(); } ! free(pwd2); printf("storing the password ... "); *************** *** 1365,1371 **** PG_CMD_OPEN; if (fprintf( ! pg, "ALTER USER \"%s\" WITH PASSWORD '%s';\n", username, pw1) < 0) { /* write failure */ exit_nicely(); --- 1277,1283 ---- PG_CMD_OPEN; if (fprintf( ! pg, "ALTER USER \"%s\" WITH PASSWORD '%s';\n", username, pwd1) < 0) { /* write failure */ exit_nicely(); *************** *** 1374,1381 **** PG_CMD_CLOSE; ! snprintf(pwpath, MAXPGPATH, "%s/global/pg_pwd", pg_data); ! if (stat(pwpath, &statbuf) != 0 || !S_ISREG(statbuf.st_mode)) { fprintf(stderr, "%s: The password file was not generated - " --- 1286,1293 ---- PG_CMD_CLOSE; ! snprintf(pwdpath, MAXPGPATH, "%s/global/pg_pwd", pg_data); ! if (stat(pwdpath, &statbuf) != 0 || !S_ISREG(statbuf.st_mode)) { fprintf(stderr, "%s: The password file was not generated - " *************** *** 1898,1904 **** * So this will need some testing on Windows. * */ - static void trapsig(int signum) { --- 1810,1815 ---- *************** *** 2009,2015 **** /* when not available, get the CTYPE setting */ lc_messages = xstrdup(setlocale(LC_CTYPE, NULL)); } ! #endif /* LC_MESSAGES */ } --- 1920,1926 ---- /* when not available, get the CTYPE setting */ lc_messages = xstrdup(setlocale(LC_CTYPE, NULL)); } ! #endif } *************** *** 2017,2023 **** * help text data * */ - char *usage_text[] = { "$CMDNAME initializes a PostgreSQL database cluster.\n", "\n", --- 1928,1933 ---- *************** *** 2117,2123 **** #if defined(__CYGWIN__) || defined(WIN32) char *exe; /* location of exe suffix in progname */ ! #endif /* defined(__CYGWIN__) || defined(WIN32) */ setlocale(LC_ALL, ""); --- 2027,2033 ---- #if defined(__CYGWIN__) || defined(WIN32) char *exe; /* location of exe suffix in progname */ ! #endif setlocale(LC_ALL, ""); *************** *** 2135,2141 **** /* strip .exe suffix, regardless of case */ *exe = '\0'; } ! #endif /* defined(__CYGWIN__) || defined(WIN32) */ if (lastsep) { --- 2045,2051 ---- /* strip .exe suffix, regardless of case */ *exe = '\0'; } ! #endif if (lastsep) { *************** *** 2317,2323 **** set_input(&features_file, "sql_features.txt"); set_input(&system_views_file, "system_views.sql"); - if (show_setting || debug) { fprintf(stderr, --- 2227,2232 ---- *************** *** 2335,2345 **** hba_file, ident_file); } - if (show_setting) exit(0); - check_input(bki_file); check_input(desc_file); check_input(hba_file); --- 2244,2252 ---- *************** *** 2388,2404 **** /* some of these are not valid on Windows */ #ifdef SIGHUP pqsignal(SIGHUP, trapsig); ! #endif /* SIGHUP */ #ifdef SIGINT pqsignal(SIGINT, trapsig); ! #endif /* SIGINT */ #ifdef SIGQUIT pqsignal(SIGQUIT, trapsig); ! #endif /* SIGQUIT */ #ifdef SIGTERM pqsignal(SIGTERM, trapsig); ! #endif /* SIGTERM */ ! /* clear this we'll use it in a few lines */ errno = 0; --- 2295,2310 ---- /* 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 /* clear this we'll use it in a few lines */ errno = 0; *************** *** 2420,2426 **** * check_data_dir() called opendir - the errno should still be hanging * around */ - if (errno == ENOENT) { printf("creating directory \"%s\" ... ", pg_data); --- 2326,2331 ---- *************** *** 2447,2455 **** set_null_conf(); ! test_buffers(); ! test_connections(); setup_config(); --- 2352,2360 ---- set_null_conf(); ! /* test connections first because it has more constraints */ test_connections(); + test_buffers(); setup_config(); *************** *** 2458,2466 **** set_short_version(short_version, "base/1"); setup_shadow(); - if (pwprompt) ! get_set_pw(); unlimit_systables(); --- 2363,2370 ---- set_short_version(short_version, "base/1"); setup_shadow(); if (pwprompt) ! get_set_pwd(); unlimit_systables(); *************** *** 2481,2493 **** make_template0(); printf("\n" ! "Success. You can now start the database server using:\n" ! "\n" ! " \"%s/postmaster\" -D \"%s\"\n" "or\n" ! " \"%s/pg_ctl\" -D \"%s\" -l logfile start\n" ! "\n", ! pgpath, pg_data, pgpath, pg_data); return 0; } --- 2385,2396 ---- make_template0(); printf("\n" ! "Success. You can now start the database server using:\n\n" ! " %s/postmaster -D %s%s%s\n" "or\n" ! " %s/pg_ctl -D %s%s%s -l logfile start\n\n", ! pgpath, QUOTE_PATH, pg_data, QUOTE_PATH, ! pgpath, QUOTE_PATH, pg_data, QUOTE_PATH); return 0; }