~ubuntu-branches/debian/sid/postgresql-9.3/sid

« back to all changes in this revision

Viewing changes to contrib/pg_upgrade/util.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 05:39:52 UTC
  • Revision ID: package-import@ubuntu.com-20130508053952-1j7uilp7mjtrvq8q
Tags: upstream-9.3~beta1
ImportĀ upstreamĀ versionĀ 9.3~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      util.c
 
3
 *
 
4
 *      utility functions
 
5
 *
 
6
 *      Copyright (c) 2010-2013, PostgreSQL Global Development Group
 
7
 *      contrib/pg_upgrade/util.c
 
8
 */
 
9
 
 
10
#include "postgres_fe.h"
 
11
 
 
12
#include "pg_upgrade.h"
 
13
 
 
14
#include <signal.h>
 
15
 
 
16
 
 
17
LogOpts         log_opts;
 
18
 
 
19
/*
 
20
 * report_status()
 
21
 *
 
22
 *      Displays the result of an operation (ok, failed, error message,...)
 
23
 */
 
24
void
 
25
report_status(eLogType type, const char *fmt,...)
 
26
{
 
27
        va_list         args;
 
28
        char            message[MAX_STRING];
 
29
 
 
30
        va_start(args, fmt);
 
31
        vsnprintf(message, sizeof(message), fmt, args);
 
32
        va_end(args);
 
33
 
 
34
        pg_log(type, "%s\n", message);
 
35
}
 
36
 
 
37
 
 
38
/* force blank output for progress display */
 
39
void
 
40
end_progress_output(void)
 
41
{
 
42
        /*
 
43
         *      In case nothing printed; pass a space so gcc doesn't complain about
 
44
         *      empty format string.
 
45
         */
 
46
        prep_status(" ");
 
47
}
 
48
 
 
49
 
 
50
/*
 
51
 * prep_status
 
52
 *
 
53
 *      Displays a message that describes an operation we are about to begin.
 
54
 *      We pad the message out to MESSAGE_WIDTH characters so that all of the "ok" and
 
55
 *      "failed" indicators line up nicely.
 
56
 *
 
57
 *      A typical sequence would look like this:
 
58
 *              prep_status("about to flarb the next %d files", fileCount );
 
59
 *
 
60
 *              if(( message = flarbFiles(fileCount)) == NULL)
 
61
 *                report_status(PG_REPORT, "ok" );
 
62
 *              else
 
63
 *                pg_log(PG_FATAL, "failed - %s\n", message );
 
64
 */
 
65
void
 
66
prep_status(const char *fmt,...)
 
67
{
 
68
        va_list         args;
 
69
        char            message[MAX_STRING];
 
70
 
 
71
        va_start(args, fmt);
 
72
        vsnprintf(message, sizeof(message), fmt, args);
 
73
        va_end(args);
 
74
 
 
75
        if (strlen(message) > 0 && message[strlen(message) - 1] == '\n')
 
76
                pg_log(PG_REPORT, "%s", message);
 
77
        else
 
78
                /* trim strings that don't end in a newline */
 
79
                pg_log(PG_REPORT, "%-*s", MESSAGE_WIDTH, message);
 
80
}
 
81
 
 
82
 
 
83
void
 
84
pg_log(eLogType type, char *fmt,...)
 
85
{
 
86
        va_list         args;
 
87
        char            message[MAX_STRING];
 
88
 
 
89
        va_start(args, fmt);
 
90
        vsnprintf(message, sizeof(message), fmt, args);
 
91
        va_end(args);
 
92
 
 
93
        /* PG_VERBOSE and PG_STATUS are only output in verbose mode */
 
94
        /* fopen() on log_opts.internal might have failed, so check it */
 
95
        if (((type != PG_VERBOSE && type != PG_STATUS) || log_opts.verbose) &&
 
96
                log_opts.internal != NULL)
 
97
        {
 
98
                if (type == PG_STATUS)
 
99
                        /* status messages need two leading spaces and a newline */
 
100
                        fprintf(log_opts.internal, "  %s\n", message);
 
101
                else
 
102
                        fprintf(log_opts.internal, "%s", message);
 
103
                fflush(log_opts.internal);
 
104
        }
 
105
 
 
106
        switch (type)
 
107
        {
 
108
                case PG_VERBOSE:
 
109
                        if (log_opts.verbose)
 
110
                                printf("%s", _(message));
 
111
                        break;
 
112
 
 
113
                case PG_STATUS:
 
114
                        /* for output to a display, do leading truncation and append \r */
 
115
                        if (isatty(fileno(stdout)))
 
116
                                /* -2 because we use a 2-space indent */
 
117
                                printf("  %s%-*.*s\r", 
 
118
                                                /* prefix with "..." if we do leading truncation */
 
119
                                                strlen(message) <= MESSAGE_WIDTH - 2 ? "" : "...",
 
120
                                                MESSAGE_WIDTH - 2, MESSAGE_WIDTH - 2,
 
121
                                                /* optional leading truncation */
 
122
                                                strlen(message) <= MESSAGE_WIDTH - 2 ? message :
 
123
                                                message + strlen(message) - MESSAGE_WIDTH + 3 + 2);
 
124
                        else
 
125
                                printf("  %s\n", _(message));
 
126
                        break;
 
127
 
 
128
                case PG_REPORT:
 
129
                case PG_WARNING:
 
130
                        printf("%s", _(message));
 
131
                        break;
 
132
 
 
133
                case PG_FATAL:
 
134
                        printf("\n%s", _(message));
 
135
                        printf("Failure, exiting\n");
 
136
                        exit(1);
 
137
                        break;
 
138
 
 
139
                default:
 
140
                        break;
 
141
        }
 
142
        fflush(stdout);
 
143
}
 
144
 
 
145
 
 
146
void
 
147
check_ok(void)
 
148
{
 
149
        /* all seems well */
 
150
        report_status(PG_REPORT, "ok");
 
151
        fflush(stdout);
 
152
}
 
153
 
 
154
 
 
155
/*
 
156
 * quote_identifier()
 
157
 *              Properly double-quote a SQL identifier.
 
158
 *
 
159
 * The result should be pg_free'd, but most callers don't bother because
 
160
 * memory leakage is not a big deal in this program.
 
161
 */
 
162
char *
 
163
quote_identifier(const char *s)
 
164
{
 
165
        char       *result = pg_malloc(strlen(s) * 2 + 3);
 
166
        char       *r = result;
 
167
 
 
168
        *r++ = '"';
 
169
        while (*s)
 
170
        {
 
171
                if (*s == '"')
 
172
                        *r++ = *s;
 
173
                *r++ = *s;
 
174
                s++;
 
175
        }
 
176
        *r++ = '"';
 
177
        *r++ = '\0';
 
178
 
 
179
        return result;
 
180
}
 
181
 
 
182
 
 
183
/*
 
184
 * get_user_info()
 
185
 * (copied from initdb.c) find the current user
 
186
 */
 
187
int
 
188
get_user_info(char **user_name)
 
189
{
 
190
        int                     user_id;
 
191
 
 
192
#ifndef WIN32
 
193
        struct passwd *pw = getpwuid(geteuid());
 
194
 
 
195
        user_id = geteuid();
 
196
#else                                                   /* the windows code */
 
197
        struct passwd_win32
 
198
        {
 
199
                int                     pw_uid;
 
200
                char            pw_name[128];
 
201
        }                       pass_win32;
 
202
        struct passwd_win32 *pw = &pass_win32;
 
203
        DWORD           pwname_size = sizeof(pass_win32.pw_name) - 1;
 
204
 
 
205
        GetUserName(pw->pw_name, &pwname_size);
 
206
 
 
207
        user_id = 1;
 
208
#endif
 
209
 
 
210
        *user_name = pg_strdup(pw->pw_name);
 
211
 
 
212
        return user_id;
 
213
}
 
214
 
 
215
 
 
216
/*
 
217
 * getErrorText()
 
218
 *
 
219
 *      Returns the text of the error message for the given error number
 
220
 *
 
221
 *      This feature is factored into a separate function because it is
 
222
 *      system-dependent.
 
223
 */
 
224
const char *
 
225
getErrorText(int errNum)
 
226
{
 
227
#ifdef WIN32
 
228
        _dosmaperr(GetLastError());
 
229
#endif
 
230
        return pg_strdup(strerror(errNum));
 
231
}
 
232
 
 
233
 
 
234
/*
 
235
 *      str2uint()
 
236
 *
 
237
 *      convert string to oid
 
238
 */
 
239
unsigned int
 
240
str2uint(const char *str)
 
241
{
 
242
        return strtoul(str, NULL, 10);
 
243
}
 
244
 
 
245
 
 
246
/*
 
247
 *      pg_putenv()
 
248
 *
 
249
 *      This is like putenv(), but takes two arguments.
 
250
 *      It also does unsetenv() if val is NULL.
 
251
 */
 
252
void
 
253
pg_putenv(const char *var, const char *val)
 
254
{
 
255
        if (val)
 
256
        {
 
257
#ifndef WIN32
 
258
                char       *envstr = (char *) pg_malloc(strlen(var) +
 
259
                                                                                                strlen(val) + 2);
 
260
 
 
261
                sprintf(envstr, "%s=%s", var, val);
 
262
                putenv(envstr);
 
263
 
 
264
                /*
 
265
                 * Do not free envstr because it becomes part of the environment on
 
266
                 * some operating systems.      See port/unsetenv.c::unsetenv.
 
267
                 */
 
268
#else
 
269
                SetEnvironmentVariableA(var, val);
 
270
#endif
 
271
        }
 
272
        else
 
273
        {
 
274
#ifndef WIN32
 
275
                unsetenv(var);
 
276
#else
 
277
                SetEnvironmentVariableA(var, "");
 
278
#endif
 
279
        }
 
280
}