diff options
author | Bruce Momjian | 2010-05-12 02:19:11 +0000 |
---|---|---|
committer | Bruce Momjian | 2010-05-12 02:19:11 +0000 |
commit | c2e9b2f288185a8569f6391ea250c7eeafa6c14b (patch) | |
tree | 408e8eb0c0aacaf177602789c02d7a416bbd59e1 /contrib/pg_upgrade/util.c | |
parent | 28e1742217716076da0700094a369eae5766974c (diff) |
Add pg_upgrade to /contrib; will be in 9.0 beta2.
Add documentation.
Supports migration from PG 8.3 and 8.4.
Diffstat (limited to 'contrib/pg_upgrade/util.c')
-rw-r--r-- | contrib/pg_upgrade/util.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c new file mode 100644 index 00000000000..f64dc4af5cc --- /dev/null +++ b/contrib/pg_upgrade/util.c @@ -0,0 +1,258 @@ +/* + * util.c + * + * utility functions + */ + +#include "pg_upgrade.h" + +#include <signal.h> + + +/* + * report_status() + * + * Displays the result of an operation (ok, failed, error message,...) + */ +void +report_status(migratorContext *ctx, eLogType type, const char *fmt,...) +{ + va_list args; + char message[MAX_STRING]; + + va_start(args, fmt); + vsnprintf(message, sizeof(message), fmt, args); + va_end(args); + + pg_log(ctx, type, "%s\n", message); +} + + +/* + * prep_status(&ctx, ) + * + * Displays a message that describes an operation we are about to begin. + * We pad the message out to MESSAGE_WIDTH characters so that all of the "ok" and + * "failed" indicators line up nicely. + * + * A typical sequence would look like this: + * prep_status(&ctx, "about to flarb the next %d files", fileCount ); + * + * if(( message = flarbFiles(fileCount)) == NULL) + * report_status(ctx, PG_REPORT, "ok" ); + * else + * pg_log(ctx, PG_FATAL, "failed - %s", message ); + */ +void +prep_status(migratorContext *ctx, const char *fmt,...) +{ + va_list args; + char message[MAX_STRING]; + + va_start(args, fmt); + vsnprintf(message, sizeof(message), fmt, args); + va_end(args); + + if (strlen(message) > 0 && message[strlen(message) - 1] == '\n') + pg_log(ctx, PG_REPORT, "%s", message); + else + pg_log(ctx, PG_REPORT, "%-" MESSAGE_WIDTH "s", message); +} + + +void +pg_log(migratorContext *ctx, eLogType type, char *fmt,...) +{ + va_list args; + char message[MAX_STRING]; + + va_start(args, fmt); + vsnprintf(message, sizeof(message), fmt, args); + va_end(args); + + if (ctx->log_fd != NULL) + { + fwrite(message, strlen(message), 1, ctx->log_fd); + /* if we are using OVERWRITE_MESSAGE, add newline */ + if (strchr(message, '\r') != NULL) + fwrite("\n", 1, 1, ctx->log_fd); + fflush(ctx->log_fd); + } + + switch (type) + { + case PG_INFO: + if (ctx->verbose) + printf("%s", _(message)); + break; + + case PG_REPORT: + case PG_WARNING: + printf("%s", _(message)); + break; + + case PG_FATAL: + printf("%s", "\n"); + printf("%s", _(message)); + exit_nicely(ctx, true); + break; + + case PG_DEBUG: + if (ctx->debug) + fprintf(ctx->debug_fd, "%s\n", _(message)); + break; + + default: + break; + } + fflush(stdout); +} + + +void +check_ok(migratorContext *ctx) +{ + /* all seems well */ + report_status(ctx, PG_REPORT, "ok"); + fflush(stdout); +} + + +/* + * quote_identifier() + * Properly double-quote a SQL identifier. + * + * The result should be pg_free'd, but most callers don't bother because + * memory leakage is not a big deal in this program. + */ +char * +quote_identifier(migratorContext *ctx, const char *s) +{ + char *result = pg_malloc(ctx, strlen(s) * 2 + 3); + char *r = result; + + *r++ = '"'; + while (*s) + { + if (*s == '"') + *r++ = *s; + *r++ = *s; + s++; + } + *r++ = '"'; + *r++ = '\0'; + + return result; +} + + +/* + * get_user_info() + * (copied from initdb.c) find the current user + */ +int +get_user_info(migratorContext *ctx, char **user_name) +{ + int user_id; + +#ifndef WIN32 + struct passwd *pw = getpwuid(geteuid()); + + user_id = geteuid(); +#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; + + GetUserName(pw->pw_name, &pwname_size); + + user_id = 1; +#endif + + *user_name = pg_strdup(ctx, pw->pw_name); + + return user_id; +} + + +void +exit_nicely(migratorContext *ctx, bool need_cleanup) +{ + stop_postmaster(ctx, true, true); + + pg_free(ctx->logfile); + + if (ctx->log_fd) + fclose(ctx->log_fd); + + if (ctx->debug_fd) + fclose(ctx->debug_fd); + + /* terminate any running instance of postmaster */ + if (ctx->postmasterPID != 0) + kill(ctx->postmasterPID, SIGTERM); + + if (need_cleanup) + { + /* + * FIXME must delete intermediate files + */ + exit(1); + } + else + exit(0); +} + + +void * +pg_malloc(migratorContext *ctx, int n) +{ + void *p = malloc(n); + + if (p == NULL) + pg_log(ctx, PG_FATAL, "%s: out of memory\n", ctx->progname); + + return p; +} + + +void +pg_free(void *p) +{ + if (p != NULL) + free(p); +} + + +char * +pg_strdup(migratorContext *ctx, const char *s) +{ + char *result = strdup(s); + + if (result == NULL) + pg_log(ctx, PG_FATAL, "%s: out of memory\n", ctx->progname); + + return result; +} + + +/* + * getErrorText() + * + * Returns the text of the error message for the given error number + * + * This feature is factored into a separate function because it is + * system-dependent. + */ +const char * +getErrorText(int errNum) +{ +#ifdef WIN32 + _dosmaperr(GetLastError()); +#endif + return strdup(strerror(errNum)); +} |