version.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * version.c
  4.  *   Routines to handle Postgres version number.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/utils/version.c,v 1.11 1999/02/13 23:22:53 momjian Exp $
  11.  *
  12.  * NOTES
  13.  * XXX eventually, should be able to handle version identifiers
  14.  * of length != 4.
  15.  *
  16.  * STANDALONE CODE - do not use error routines as this code is linked with
  17.  * stuff that does not cinterface.a
  18.  *-------------------------------------------------------------------------
  19.  */
  20. #include <sys/types.h>
  21. #include <sys/file.h>
  22. #include <fcntl.h> /* For open() flags */
  23. #include <sys/stat.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include <stdio.h>
  27. #include <unistd.h>
  28. #include <errno.h>
  29. #include "postgres.h"
  30. #include "storage/fd.h" /* for O_ */
  31. #include "version.h"
  32. static void
  33. PathSetVersionFilePath(const char *path, char *filepathbuf)
  34. {
  35. /*----------------------------------------------------------------------------
  36.   PathSetVersionFilePath
  37.   Destructively change "filepathbuf" to contain the concatenation of "path"
  38.   and the name of the version file name.
  39. ----------------------------------------------------------------------------*/
  40. if (strlen(path) > (MAXPGPATH - sizeof(PG_VERFILE) - 1))
  41. *filepathbuf = '';
  42. else
  43. sprintf(filepathbuf, "%s%c%s", path, SEP_CHAR, PG_VERFILE);
  44. }
  45. void
  46. ValidatePgVersion(const char *path, char **reason_p)
  47. {
  48. /*----------------------------------------------------------------------------
  49. Determine whether the PG_VERSION file in directory <path> indicates
  50. a data version compatible with the version of this program.
  51. If compatible, return <*reason_p> == NULL. Otherwise, malloc space,
  52. fill it with a text string explaining how it isn't compatible (or why
  53. we can't tell), and return a pointer to that space as <*reason_p>.
  54. -----------------------------------------------------------------------------*/
  55. int fd;
  56. char version[4];
  57. char full_path[MAXPGPATH + 1];
  58. PathSetVersionFilePath(path, full_path);
  59. #ifndef __CYGWIN32__
  60. if ((fd = open(full_path, O_RDONLY, 0)) == -1)
  61. #else
  62. if ((fd = open(full_path, O_RDONLY | O_BINARY, 0)) == -1)
  63. #endif
  64. {
  65. *reason_p = malloc(200);
  66. sprintf(*reason_p, "File '%s' does not exist or no read permission.", full_path);
  67. }
  68. else
  69. {
  70. if (read(fd, version, 4) < 4 ||
  71. !isascii(version[0]) || !isdigit(version[0]) ||
  72. version[1] != '.' ||
  73. !isascii(version[2]) || !isdigit(version[2]) ||
  74. version[3] != 'n')
  75. {
  76. *reason_p = malloc(200);
  77. sprintf(*reason_p, "File '%s' does not have a valid format "
  78. "for a PG_VERSION file.", full_path);
  79. }
  80. else
  81. {
  82. if (version[2] != PG_VERSION[0] ||
  83. version[0] != PG_RELEASE[0])
  84. {
  85. *reason_p = malloc(200);
  86. sprintf(*reason_p,
  87. "Version number in file '%s' should be %s.%s, "
  88. "not %c.%c.",
  89. full_path,
  90. PG_RELEASE, PG_VERSION, version[0], version[2]);
  91. }
  92. else
  93. *reason_p = NULL;
  94. }
  95. close(fd);
  96. }
  97. }
  98. void
  99. SetPgVersion(const char *path, char **reason_p)
  100. {
  101. /*---------------------------------------------------------------------------
  102.   Create the PG_VERSION file in the directory <path>.
  103.   If we fail, allocate storage, fill it with a text string explaining why,
  104.   and return a pointer to that storage as <*reason_p>. If we succeed,
  105.   return *reason_p = NULL.
  106. ---------------------------------------------------------------------------*/
  107. int fd;
  108. char version[4];
  109. char full_path[MAXPGPATH + 1];
  110. PathSetVersionFilePath(path, full_path);
  111. #ifndef __CYGWIN32__
  112. fd = open(full_path, O_WRONLY | O_CREAT | O_EXCL, 0666);
  113. #else
  114. fd = open(full_path, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
  115. #endif
  116. if (fd < 0)
  117. {
  118. *reason_p = malloc(100 + strlen(full_path));
  119. sprintf(*reason_p,
  120. "Unable to create file '%s', errno from open(): %s (%d).",
  121. full_path, strerror(errno), errno);
  122. }
  123. else
  124. {
  125. int rc; /* return code from some function we call */
  126. version[0] = PG_RELEASE[0];
  127. version[1] = '.';
  128. version[2] = PG_VERSION[0];
  129. version[3] = 'n';
  130. rc = write(fd, version, 4);
  131. if (rc != 4)
  132. {
  133. *reason_p = malloc(100 + strlen(full_path));
  134. sprintf(*reason_p,
  135. "Failed to write to file '%s', after it was already "
  136. "open.  Errno from write(): %s (%d)",
  137. full_path, strerror(errno), errno);
  138. }
  139. else
  140. *reason_p = NULL;
  141. close(fd);
  142. }
  143. }