PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/pg_upgrade/util.c

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