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