179 lines
4.8 KiB
C
179 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 */
|