1
0
Fork 0
sattools/qfits/src/fits_md5.c

186 lines
4.8 KiB
C

/*----------------------------------------------------------------------------*/
/**
@file fits_md5.c
@author N. Devillard
@date May 2001
@version $Revision: 1.8 $
@brief FITS data block MD5 computation routine.
This module offers MD5 computation over all data areas of a FITS file.
*/
/*----------------------------------------------------------------------------*/
/*
$Id: fits_md5.c,v 1.8 2003/01/23 09:13:18 yjung Exp $
$Author: yjung $
$Date: 2003/01/23 09:13:18 $
$Revision: 1.8 $
*/
/*-----------------------------------------------------------------------------
Includes
-----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "md5.h"
#include "fits_std.h"
#include "qerror.h"
/*-----------------------------------------------------------------------------
Defines
-----------------------------------------------------------------------------*/
/** Size of an MD5 hash in bytes (32 bytes are 128 bits) */
#define MD5HASHSZ 32
/*-----------------------------------------------------------------------------
Function code
-----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/**
@brief Compute the MD5 hash of data zones in a FITS file.
@param filename Name of the FITS file to examine.
@return 1 statically allocated character string, or NULL.
This function expects the name of a FITS file.
It will compute the MD5 hash on all data blocks in the main data section
and possibly extensions (including zero-padding blocks if necessary) and
return it as a string suitable for inclusion into a FITS keyword.
The returned string is statically allocated inside this function,
so do not free it or modify it. This function returns NULL in case
of error.
*/
/*----------------------------------------------------------------------------*/
char *
qfits_datamd5 (char *filename)
{
static char datamd5[MD5HASHSZ + 1];
struct MD5Context ctx;
unsigned char digest[16];
FILE *in;
char buf[FITS_BLOCK_SIZE];
char *buf_c;
int i;
int in_header;
int check_fits;
/* Check entries */
if (filename == NULL)
return NULL;
/* Open input file */
if ((in = fopen (filename, "r")) == NULL)
{
qfits_error ("cannot open file %s", filename);
return NULL;
}
/* Initialize all variables */
MD5Init (&ctx);
in_header = 1;
check_fits = 0;
/* Loop over input file */
while (fread (buf, 1, FITS_BLOCK_SIZE, in) == FITS_BLOCK_SIZE)
{
/* First time in the loop: check the file is FITS */
if (check_fits == 0)
{
/* Examine first characters in block */
if (buf[0] != 'S' ||
buf[1] != 'I' ||
buf[2] != 'M' ||
buf[3] != 'P' ||
buf[4] != 'L' ||
buf[5] != 'E' ||
buf[6] != ' ' || buf[7] != ' ' || buf[8] != '=')
{
qfits_error ("file [%s] is not FITS\n", filename);
fclose (in);
return NULL;
}
else
{
check_fits = 1;
}
}
if (in_header)
{
buf_c = buf;
for (i = 0; i < FITS_NCARDS; i++)
{
if (buf_c[0] == 'E' &&
buf_c[1] == 'N' && buf_c[2] == 'D' && buf_c[3] == ' ')
{
in_header = 0;
break;
}
buf_c += FITS_LINESZ;
}
}
else
{
/* If current block is a data block */
/* Try to locate an extension header */
if (buf[0] == 'X' &&
buf[1] == 'T' &&
buf[2] == 'E' &&
buf[3] == 'N' &&
buf[4] == 'S' &&
buf[5] == 'I' &&
buf[6] == 'O' && buf[7] == 'N' && buf[8] == '=')
{
in_header = 1;
buf_c = buf;
for (i = 0; i < FITS_NCARDS; i++)
{
/* Try to find an END marker in this block */
if (buf_c[0] == 'E' &&
buf_c[1] == 'N' && buf_c[2] == 'D' && buf_c[3] == ' ')
{
/* Found END marker in same block as XTENSION */
in_header = 0;
break;
}
buf_c += FITS_LINESZ;
}
}
else
{
MD5Update (&ctx, (unsigned char *) buf, FITS_BLOCK_SIZE);
}
}
}
fclose (in);
if (check_fits == 0)
{
/* Never went through the read loop: file is not FITS */
qfits_error ("file [%s] is not FITS", filename);
return NULL;
}
/* Got to the end of file: summarize */
MD5Final (digest, &ctx);
/* Write digest into a string */
sprintf (datamd5,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[0],
digest[1],
digest[2],
digest[3],
digest[4],
digest[5],
digest[6],
digest[7],
digest[8],
digest[9],
digest[10],
digest[11], digest[12], digest[13], digest[14], digest[15]);
return datamd5;
}
/* vim: set ts=4 et sw=4 tw=75 */