|
|
@ -52,6 +52,12 @@ static unsigned int blockSize = 0;
|
|
|
|
/* Current block in file */
|
|
|
|
/* Current block in file */
|
|
|
|
static unsigned int currentBlock = 0;
|
|
|
|
static unsigned int currentBlock = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Segment size in bytes */
|
|
|
|
|
|
|
|
static unsigned int segmentSize = RELSEG_SIZE * BLCKSZ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Number of current segment */
|
|
|
|
|
|
|
|
static unsigned int segmentNumber = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* Offset of current block */
|
|
|
|
/* Offset of current block */
|
|
|
|
static unsigned int pageOffset = 0;
|
|
|
|
static unsigned int pageOffset = 0;
|
|
|
|
|
|
|
|
|
|
|
@ -61,6 +67,9 @@ static unsigned int bytesToFormat = 0;
|
|
|
|
/* Block version number */
|
|
|
|
/* Block version number */
|
|
|
|
static unsigned int blockVersion = 0;
|
|
|
|
static unsigned int blockVersion = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Program exit code */
|
|
|
|
|
|
|
|
static int exitCode = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/***
|
|
|
|
/***
|
|
|
|
* Function Prototypes
|
|
|
|
* Function Prototypes
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -95,7 +104,7 @@ DisplayOptions(unsigned int validOptions)
|
|
|
|
FD_VERSION, FD_PG_VERSION);
|
|
|
|
FD_VERSION, FD_PG_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
printf
|
|
|
|
printf
|
|
|
|
("\nUsage: pg_filedump [-abcdfhikxy] [-R startblock [endblock]] [-S blocksize] file\n\n"
|
|
|
|
("\nUsage: pg_filedump [-abcdfhikxy] [-R startblock [endblock]] [-S blocksize] [-s segsize] [-n segnumber] file\n\n"
|
|
|
|
"Display formatted contents of a PostgreSQL heap/index/control file\n"
|
|
|
|
"Display formatted contents of a PostgreSQL heap/index/control file\n"
|
|
|
|
"Defaults are: relative addressing, range of the entire file, block\n"
|
|
|
|
"Defaults are: relative addressing, range of the entire file, block\n"
|
|
|
|
" size as listed on block 0 in the file\n\n"
|
|
|
|
" size as listed on block 0 in the file\n\n"
|
|
|
@ -114,6 +123,8 @@ DisplayOptions(unsigned int validOptions)
|
|
|
|
" indexed from 0)\n" " [startblock]: block to start at\n"
|
|
|
|
" indexed from 0)\n" " [startblock]: block to start at\n"
|
|
|
|
" [endblock]: block to end at\n"
|
|
|
|
" [endblock]: block to end at\n"
|
|
|
|
" A startblock without an endblock will format the single block\n"
|
|
|
|
" A startblock without an endblock will format the single block\n"
|
|
|
|
|
|
|
|
" -s Force segment size to [segsize]\n"
|
|
|
|
|
|
|
|
" -n Force segment number to [segnumber]\n"
|
|
|
|
" -S Force block size to [blocksize]\n"
|
|
|
|
" -S Force block size to [blocksize]\n"
|
|
|
|
" -x Force interpreted formatting of block items as index items\n"
|
|
|
|
" -x Force interpreted formatting of block items as index items\n"
|
|
|
|
" -y Force interpreted formatting of block items as heap items\n\n"
|
|
|
|
" -y Force interpreted formatting of block items as heap items\n\n"
|
|
|
@ -124,6 +135,31 @@ DisplayOptions(unsigned int validOptions)
|
|
|
|
"\nReport bugs to <pgsql-bugs@postgresql.org>\n");
|
|
|
|
"\nReport bugs to <pgsql-bugs@postgresql.org>\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Determine segment number by segment file name. For instance, if file
|
|
|
|
|
|
|
|
* name is /path/to/xxxx.7 procedure returns 7. Default return value is 0.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
|
|
|
GetSegmentNumberFromFileName(const char* fileName)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int segnumOffset = strlen(fileName) - 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(segnumOffset < 0)
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(isdigit(fileName[segnumOffset]))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
segnumOffset--;
|
|
|
|
|
|
|
|
if(segnumOffset < 0)
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(fileName[segnumOffset] != '.')
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return atoi(&fileName[segnumOffset+1]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Iterate through the provided options and set the option flags. */
|
|
|
|
/* Iterate through the provided options and set the option flags. */
|
|
|
|
/* An error will result in a positive rc and will force a display */
|
|
|
|
/* An error will result in a positive rc and will force a display */
|
|
|
|
/* of the usage information. This routine returns enum */
|
|
|
|
/* of the usage information. This routine returns enum */
|
|
|
@ -158,6 +194,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Missing range start identifier.\n");
|
|
|
|
printf("Error: Missing range start identifier.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -172,6 +209,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Invalid range start identifier <%s>.\n",
|
|
|
|
printf("Error: Invalid range start identifier <%s>.\n",
|
|
|
|
optionString);
|
|
|
|
optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -197,6 +235,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Requested block range start <%d> is "
|
|
|
|
printf("Error: Requested block range start <%d> is "
|
|
|
|
"greater than end <%d>.\n", blockStart, range);
|
|
|
|
"greater than end <%d>.\n", blockStart, range);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -232,6 +271,74 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Invalid block size requested <%s>.\n",
|
|
|
|
printf("Error: Invalid block size requested <%s>.\n",
|
|
|
|
optionString);
|
|
|
|
optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for the special case where the user forces a segment size. */
|
|
|
|
|
|
|
|
else if ((optionStringLength == 2)
|
|
|
|
|
|
|
|
&& (strcmp(optionString, "-s") == 0))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int localSegmentSize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SET_OPTION(segmentOptions, SEGMENT_SIZE_FORCED, 's');
|
|
|
|
|
|
|
|
/* Only accept the forced size option once */
|
|
|
|
|
|
|
|
if (rc == OPT_RC_DUPLICATE)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The token immediately following -s is the segment size */
|
|
|
|
|
|
|
|
if (x >= (numOptions - 2))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
|
|
|
|
printf("Error: Missing segment size identifier.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Next option encountered must be forced segment size */
|
|
|
|
|
|
|
|
optionString = options[++x];
|
|
|
|
|
|
|
|
if ((localSegmentSize = GetOptionValue(optionString)) > 0)
|
|
|
|
|
|
|
|
segmentSize = (unsigned int) localSegmentSize;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
|
|
|
|
printf("Error: Invalid segment size requested <%s>.\n",
|
|
|
|
|
|
|
|
optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for the special case where the user forces a segment number */
|
|
|
|
|
|
|
|
/* instead of having the tool determine it by file name. */
|
|
|
|
|
|
|
|
else if ((optionStringLength == 2)
|
|
|
|
|
|
|
|
&& (strcmp(optionString, "-n") == 0))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int localSegmentNumber;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SET_OPTION(segmentOptions, SEGMENT_NUMBER_FORCED, 'n');
|
|
|
|
|
|
|
|
/* Only accept the forced segment number option once */
|
|
|
|
|
|
|
|
if (rc == OPT_RC_DUPLICATE)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The token immediately following -n is the segment number */
|
|
|
|
|
|
|
|
if (x >= (numOptions - 2))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
|
|
|
|
printf("Error: Missing segment number identifier.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Next option encountered must be forced segment number */
|
|
|
|
|
|
|
|
optionString = options[++x];
|
|
|
|
|
|
|
|
if ((localSegmentNumber = GetOptionValue(optionString)) > 0)
|
|
|
|
|
|
|
|
segmentNumber = (unsigned int) localSegmentNumber;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
|
|
|
|
printf("Error: Invalid segment number requested <%s>.\n",
|
|
|
|
|
|
|
|
optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -243,11 +350,16 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
fp = fopen(optionString, "rb");
|
|
|
|
fp = fopen(optionString, "rb");
|
|
|
|
if (fp)
|
|
|
|
if (fp)
|
|
|
|
|
|
|
|
{
|
|
|
|
fileName = options[x];
|
|
|
|
fileName = options[x];
|
|
|
|
|
|
|
|
if(!(segmentOptions & SEGMENT_NUMBER_FORCED))
|
|
|
|
|
|
|
|
segmentNumber = GetSegmentNumberFromFileName(fileName);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
rc = OPT_RC_FILE;
|
|
|
|
rc = OPT_RC_FILE;
|
|
|
|
printf("Error: Could not open file <%s>.\n", optionString);
|
|
|
|
printf("Error: Could not open file <%s>.\n", optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -261,6 +373,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
rc = OPT_RC_FILE;
|
|
|
|
rc = OPT_RC_FILE;
|
|
|
|
printf("Error: Missing file name to dump.\n");
|
|
|
|
printf("Error: Missing file name to dump.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -274,6 +387,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Invalid option string <%s>.\n", optionString);
|
|
|
|
printf("Error: Invalid option string <%s>.\n", optionString);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -335,6 +449,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Options <y> and <x> are "
|
|
|
|
printf("Error: Options <y> and <x> are "
|
|
|
|
"mutually exclusive.\n");
|
|
|
|
"mutually exclusive.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
@ -346,12 +461,14 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Options <x> and <y> are "
|
|
|
|
printf("Error: Options <x> and <y> are "
|
|
|
|
"mutually exclusive.\n");
|
|
|
|
"mutually exclusive.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Unknown option <%c>.\n", optionString[y]);
|
|
|
|
printf("Error: Unknown option <%c>.\n", optionString[y]);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -362,7 +479,10 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (rc == OPT_RC_DUPLICATE)
|
|
|
|
if (rc == OPT_RC_DUPLICATE)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf("Error: Duplicate option listed <%c>.\n", duplicateSwitch);
|
|
|
|
printf("Error: Duplicate option listed <%c>.\n", duplicateSwitch);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If the user requested a control file dump, a pure binary */
|
|
|
|
/* If the user requested a control file dump, a pure binary */
|
|
|
|
/* block dump or a non-interpreted formatted dump, mask off */
|
|
|
|
/* block dump or a non-interpreted formatted dump, mask off */
|
|
|
@ -379,6 +499,7 @@ ConsumeOptions(int numOptions, char **options)
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
rc = OPT_RC_INVALID;
|
|
|
|
printf("Error: Invalid options used for Control File dump.\n"
|
|
|
|
printf("Error: Invalid options used for Control File dump.\n"
|
|
|
|
" Only options <Sf> may be used with <c>.\n");
|
|
|
|
" Only options <Sf> may be used with <c>.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -446,8 +567,12 @@ GetBlockSize()
|
|
|
|
if (bytesRead == pageHeaderSize)
|
|
|
|
if (bytesRead == pageHeaderSize)
|
|
|
|
localSize = (unsigned int) PageGetPageSize(&localCache);
|
|
|
|
localSize = (unsigned int) PageGetPageSize(&localCache);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
printf("Error: Unable to read full page header from block 0.\n"
|
|
|
|
printf("Error: Unable to read full page header from block 0.\n"
|
|
|
|
" ===> Read %u bytes", bytesRead);
|
|
|
|
" ===> Read %u bytes\n", bytesRead);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (localSize);
|
|
|
|
return (localSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -687,24 +812,34 @@ FormatHeader(Page page, BlockNumber blkno)
|
|
|
|
|| (pageHeader->pd_lower > blockSize)
|
|
|
|
|| (pageHeader->pd_lower > blockSize)
|
|
|
|
|| (pageHeader->pd_upper < pageHeader->pd_lower)
|
|
|
|
|| (pageHeader->pd_upper < pageHeader->pd_lower)
|
|
|
|
|| (pageHeader->pd_special > blockSize))
|
|
|
|
|| (pageHeader->pd_special > blockSize))
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Invalid header information.\n\n");
|
|
|
|
printf(" Error: Invalid header information.\n\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (blockOptions & BLOCK_CHECKSUMS)
|
|
|
|
if (blockOptions & BLOCK_CHECKSUMS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16 calc_checksum = pg_checksum_page(page, blkno);
|
|
|
|
uint32 delta = (segmentSize/blockSize)*segmentNumber;
|
|
|
|
|
|
|
|
uint16 calc_checksum = pg_checksum_page(page, delta + blkno);
|
|
|
|
|
|
|
|
|
|
|
|
if (calc_checksum != pageHeader->pd_checksum)
|
|
|
|
if (calc_checksum != pageHeader->pd_checksum)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: checksum failure: calculated 0x%04x.\n\n",
|
|
|
|
printf(" Error: checksum failure: calculated 0x%04x.\n\n",
|
|
|
|
calc_checksum);
|
|
|
|
calc_checksum);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If we have reached the end of file while interpreting the header, let */
|
|
|
|
/* If we have reached the end of file while interpreting the header, let */
|
|
|
|
/* the user know about it */
|
|
|
|
/* the user know about it */
|
|
|
|
if (rc == EOF_ENCOUNTERED)
|
|
|
|
if (rc == EOF_ENCOUNTERED)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf
|
|
|
|
printf
|
|
|
|
(" Error: End of block encountered within the header."
|
|
|
|
(" Error: End of block encountered within the header."
|
|
|
|
" Bytes read: %4u.\n\n", bytesToFormat);
|
|
|
|
" Bytes read: %4u.\n\n", bytesToFormat);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* A request to dump the formatted binary of the block (header, */
|
|
|
|
/* A request to dump the formatted binary of the block (header, */
|
|
|
|
/* items and special section). It's best to dump even on an error */
|
|
|
|
/* items and special section). It's best to dump even on an error */
|
|
|
@ -739,8 +874,11 @@ FormatItemBlock(Page page)
|
|
|
|
if (maxOffset == 0)
|
|
|
|
if (maxOffset == 0)
|
|
|
|
printf(" Empty block - no items listed \n\n");
|
|
|
|
printf(" Empty block - no items listed \n\n");
|
|
|
|
else if ((maxOffset < 0) || (maxOffset > blockSize))
|
|
|
|
else if ((maxOffset < 0) || (maxOffset > blockSize))
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Item index corrupt on block. Offset: <%d>.\n\n",
|
|
|
|
printf(" Error: Item index corrupt on block. Offset: <%d>.\n\n",
|
|
|
|
maxOffset);
|
|
|
|
maxOffset);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int formatAs;
|
|
|
|
int formatAs;
|
|
|
@ -813,9 +951,12 @@ FormatItemBlock(Page page)
|
|
|
|
/* formatting */
|
|
|
|
/* formatting */
|
|
|
|
if ((itemOffset + itemSize > blockSize) ||
|
|
|
|
if ((itemOffset + itemSize > blockSize) ||
|
|
|
|
(itemOffset + itemSize > bytesToFormat))
|
|
|
|
(itemOffset + itemSize > bytesToFormat))
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Item contents extend beyond block.\n"
|
|
|
|
printf(" Error: Item contents extend beyond block.\n"
|
|
|
|
" BlockSize<%d> Bytes Read<%d> Item Start<%d>.\n",
|
|
|
|
" BlockSize<%d> Bytes Read<%d> Item Start<%d>.\n",
|
|
|
|
blockSize, bytesToFormat, itemOffset + itemSize);
|
|
|
|
blockSize, bytesToFormat, itemOffset + itemSize);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* If the user requests that the items be interpreted as */
|
|
|
|
/* If the user requests that the items be interpreted as */
|
|
|
@ -853,7 +994,10 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
if (numBytes < SizeOfIptrData)
|
|
|
|
if (numBytes < SizeOfIptrData)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (numBytes)
|
|
|
|
if (numBytes)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: This item does not look like an index item.\n");
|
|
|
|
printf(" Error: This item does not look like an index item.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -869,8 +1013,11 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
IndexTupleHasVarwidths(itup) ? 1 : 0);
|
|
|
|
IndexTupleHasVarwidths(itup) ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (numBytes != IndexTupleSize(itup))
|
|
|
|
if (numBytes != IndexTupleSize(itup))
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
"Internal <%d>.\n", numBytes, (int) IndexTupleSize(itup));
|
|
|
|
"Internal <%d>.\n", numBytes, (int) IndexTupleSize(itup));
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (formatAs == ITEM_SPG_INNER)
|
|
|
|
else if (formatAs == ITEM_SPG_INNER)
|
|
|
@ -879,7 +1026,10 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
if (numBytes < SGITHDRSZ)
|
|
|
|
if (numBytes < SGITHDRSZ)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (numBytes)
|
|
|
|
if (numBytes)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: This item does not look like an SPGiST item.\n");
|
|
|
|
printf(" Error: This item does not look like an SPGiST item.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -892,8 +1042,11 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
itup->prefixSize);
|
|
|
|
itup->prefixSize);
|
|
|
|
|
|
|
|
|
|
|
|
if (numBytes != itup->size)
|
|
|
|
if (numBytes != itup->size)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
"Internal <%d>.\n", numBytes, (int) itup->size);
|
|
|
|
"Internal <%d>.\n", numBytes, (int) itup->size);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (itup->prefixSize == MAXALIGN(itup->prefixSize))
|
|
|
|
else if (itup->prefixSize == MAXALIGN(itup->prefixSize))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
@ -935,7 +1088,10 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
if (numBytes < SGLTHDRSZ)
|
|
|
|
if (numBytes < SGLTHDRSZ)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (numBytes)
|
|
|
|
if (numBytes)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: This item does not look like an SPGiST item.\n");
|
|
|
|
printf(" Error: This item does not look like an SPGiST item.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -949,8 +1105,11 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
itup->heapPtr.ip_posid);
|
|
|
|
itup->heapPtr.ip_posid);
|
|
|
|
|
|
|
|
|
|
|
|
if (numBytes != itup->size)
|
|
|
|
if (numBytes != itup->size)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
printf(" Error: Item size difference. Given <%u>, "
|
|
|
|
"Internal <%d>.\n", numBytes, (int) itup->size);
|
|
|
|
"Internal <%d>.\n", numBytes, (int) itup->size);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
@ -961,7 +1120,10 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
if (numBytes < alignedSize)
|
|
|
|
if (numBytes < alignedSize)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (numBytes)
|
|
|
|
if (numBytes)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: This item does not look like a heap item.\n");
|
|
|
|
printf(" Error: This item does not look like a heap item.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1068,10 +1230,14 @@ FormatItem(unsigned int numBytes, unsigned int startIndex,
|
|
|
|
* array
|
|
|
|
* array
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (computedLength != localHoff)
|
|
|
|
if (computedLength != localHoff)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf
|
|
|
|
printf
|
|
|
|
(" Error: Computed header length not equal to header size.\n"
|
|
|
|
(" Error: Computed header length not equal to header size.\n"
|
|
|
|
" Computed <%u> Header: <%d>\n", computedLength,
|
|
|
|
" Computed <%u> Header: <%d>\n", computedLength,
|
|
|
|
localHoff);
|
|
|
|
localHoff);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if ((infoMask & HEAP_HASNULL) && bitmapLength)
|
|
|
|
else if ((infoMask & HEAP_HASNULL) && bitmapLength)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
printf(" t_bits: ");
|
|
|
|
printf(" t_bits: ");
|
|
|
@ -1107,6 +1273,7 @@ FormatSpecial()
|
|
|
|
case SPEC_SECT_ERROR_UNKNOWN:
|
|
|
|
case SPEC_SECT_ERROR_UNKNOWN:
|
|
|
|
case SPEC_SECT_ERROR_BOUNDARY:
|
|
|
|
case SPEC_SECT_ERROR_BOUNDARY:
|
|
|
|
printf(" Error: Invalid special section encountered.\n");
|
|
|
|
printf(" Error: Invalid special section encountered.\n");
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case SPEC_SECT_SEQUENCE:
|
|
|
|
case SPEC_SECT_SEQUENCE:
|
|
|
@ -1261,6 +1428,7 @@ FormatSpecial()
|
|
|
|
/* No idea what type of special section this is */
|
|
|
|
/* No idea what type of special section this is */
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
printf(" Unknown special section type. Type: <%u>.\n", specialType);
|
|
|
|
printf(" Unknown special section type. Type: <%u>.\n", specialType);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1268,8 +1436,12 @@ FormatSpecial()
|
|
|
|
if (blockOptions & BLOCK_FORMAT)
|
|
|
|
if (blockOptions & BLOCK_FORMAT)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (specialType == SPEC_SECT_ERROR_BOUNDARY)
|
|
|
|
if (specialType == SPEC_SECT_ERROR_BOUNDARY)
|
|
|
|
|
|
|
|
{
|
|
|
|
printf(" Error: Special section points off page."
|
|
|
|
printf(" Error: Special section points off page."
|
|
|
|
" Unable to dump contents.\n");
|
|
|
|
" Unable to dump contents.\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
FormatBinary(specialSize, specialOffset);
|
|
|
|
FormatBinary(specialSize, specialOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1450,6 +1622,8 @@ FormatControl()
|
|
|
|
/* If we have an error, force a formatted dump so we can see */
|
|
|
|
/* If we have an error, force a formatted dump so we can see */
|
|
|
|
/* where things are going wrong */
|
|
|
|
/* where things are going wrong */
|
|
|
|
controlOptions |= CONTROL_FORMAT;
|
|
|
|
controlOptions |= CONTROL_FORMAT;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Dump hex and ascii representation of data */
|
|
|
|
/* Dump hex and ascii representation of data */
|
|
|
@ -1539,6 +1713,7 @@ DumpFileContents()
|
|
|
|
printf("Error: Seek error encountered before requested "
|
|
|
|
printf("Error: Seek error encountered before requested "
|
|
|
|
"start block <%d>.\n", blockStart);
|
|
|
|
"start block <%d>.\n", blockStart);
|
|
|
|
contentsToDump = 0;
|
|
|
|
contentsToDump = 0;
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
currentBlock = blockStart;
|
|
|
|
currentBlock = blockStart;
|
|
|
@ -1633,8 +1808,11 @@ main(int argv, char **argc)
|
|
|
|
if (buffer)
|
|
|
|
if (buffer)
|
|
|
|
DumpFileContents();
|
|
|
|
DumpFileContents();
|
|
|
|
else
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
printf("\nError: Unable to create buffer of size <%d>.\n",
|
|
|
|
printf("\nError: Unable to create buffer of size <%d>.\n",
|
|
|
|
blockSize);
|
|
|
|
blockSize);
|
|
|
|
|
|
|
|
exitCode = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1645,5 +1823,5 @@ main(int argv, char **argc)
|
|
|
|
if (buffer)
|
|
|
|
if (buffer)
|
|
|
|
free(buffer);
|
|
|
|
free(buffer);
|
|
|
|
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
exit(exitCode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|