I had a need to read such things as the backend locale and the catalog
version number from the current database, and couldn't find any existing
program to do that.

The attached utility produces this output:

linda:~$ pg_controldata
Log file id:                          0
Log file segment:                     5
Last modified:                        Wed Feb  7 19:35:47 2001
Database block size:                  8192
Blocks per segment of large relation: 131072
Catalog version number:               200101061
LC_COLLATE:                           en_GB
LC_CTYPE:                             en_GB
Log archive directory:                


/* pg_controldata
 *
 * reads the data from $PGDATA/global/pg_control
 *
 * copyright (c) Oliver Elphick <[EMAIL PROTECTED]>, 2001;
 * licence: BSD
 *
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


typedef unsigned int uint32;

#include "config.h"
#include "access/xlogdefs.h"

/*
 * #include "access/xlog.h"
 * #include "c.h"
 */

/* The following definitions are extracted from access/xlog.h and its
 * recursive includes. There is too much initialisation needed if
 * they are included direct. Perhaps someone more knowledgeable can
 * fix that.
 */
typedef struct crc64
{
	uint32      crc1;
	uint32      crc2;
} crc64;

#define LOCALE_NAME_BUFLEN  128

typedef enum DBState
{
	DB_STARTUP = 0,
	DB_SHUTDOWNED,
	DB_SHUTDOWNING,
	DB_IN_RECOVERY,
	DB_IN_PRODUCTION
} DBState;


typedef struct ControlFileData
{
   crc64    crc;
   uint32      logId;         /* current log file id */
   uint32      logSeg;        /* current log file segment (1-based) */
   struct 
	XLogRecPtr	checkPoint;    /* last check point record ptr */
   time_t      time;       /* time stamp of last modification */
   DBState     state;         /* see enum above */

   /*
    * this data is used to make sure that configuration of this DB is
    * compatible with the backend executable
    */
   uint32      blcksz;        /* block size for this DB */
   uint32      relseg_size;   /* blocks per segment of large relation */
   uint32      catalog_version_no;     /* internal version number */
   /* active locales --- "C" if compiled without USE_LOCALE: */
   char     lc_collate[LOCALE_NAME_BUFLEN];
   char     lc_ctype[LOCALE_NAME_BUFLEN];

   /*
    * important directory locations
    */
   char     archdir[MAXPGPATH];     /* where to move offline log files */
} ControlFileData;

int main() {
	ControlFileData ControlFile;
	int fd;
	char ControlFilePath[MAXPGPATH];
	char *DataDir;
	char tmdt[32];

	DataDir = getenv("PGDATA");
	if ( DataDir == NULL ) {
		fprintf(stderr,"PGDATA is not defined\n");
		exit(1);
	}

	snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);

	if ((fd = open(ControlFilePath, O_RDONLY)) == -1) {
		perror("Failed to open $PGDATA/global/pg_control for reading");
		exit(2);
	}

	read(fd, &ControlFile, sizeof(ControlFileData));
	strftime(tmdt, 32, "%c", localtime(&(ControlFile.time)));

	printf("Log file id:                          %u\n"
	       "Log file segment:                     %u\n"
			 "Last modified:                        %s\n"
			 "Database block size:                  %u\n"
			 "Blocks per segment of large relation: %u\n"
			 "Catalog version number:               %u\n"
			 "LC_COLLATE:                           %s\n"
			 "LC_CTYPE:                             %s\n"
			 "Log archive directory:                %s\n",
			 ControlFile.logId,
			 ControlFile.logSeg,
			 tmdt,
			 ControlFile.blcksz,
			 ControlFile.relseg_size,
			 ControlFile.catalog_version_no,
			 ControlFile.lc_collate,
			 ControlFile.lc_ctype,
			 ControlFile.archdir);
	
	return (0);
}

Oliver Elphick                                [EMAIL PROTECTED]
Isle of Wight                              http://www.lfix.co.uk/oliver
PGP: 1024R/32B8FAA1: 97 EA 1D 47 72 3F 28 47  6B 7E 39 CC 56 E4 C1 47
GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839  932A 614D 4C34 3E1D 0C1C
                 ========================================
     "But the LORD is in his holy temple; let all the earth 
      keep silence before him."           Habakkuk 2:20 

Reply via email to