/* $Cambridge: hermes/src/prayer/accountd/checksum.c,v 1.2 2003/04/16 09:02:41 dpc22 Exp $ */
/************************************************
* Prayer - a Webmail Interface *
************************************************/
/* Copyright (c) University of Cambridge 2000 - 2002 */
/* See the file NOTICE for conditions of use and distribution. */
/* Little snippet of code to calculate file checksum and compare with
* current value. Rather strange little checksum routine: just happens
* to be compatible with what we are using at the moment... */
#include "accountd.h"
/* checksum_hash_line() **************************************************
*
* Convert single line of input into checksum value
* line: Line to checksum
* maxlen: Maximum length to checksum
************************************************************************/
static int checksum_hash_line(char *line, unsigned int maxlen)
{
unsigned int total;
unsigned int i;
char *p;
total = 0;
for (i = 0, p = line; *p != '\0' && *p != '\n' && i < maxlen; p++, i++) {
total += (((unsigned int) *p) * (i + 1));
}
return (total % 65536);
}
/* checksum_test() ********************************************************
*
* Calculate checksum value for a string.
* config: Global state
* existing: Returns existing checksum found in file
* current: Returns current checksum value for file
*
* Returns: T => Was able to checksum .forward file
*************************************************************************/
BOOL
checksum_test(struct config * config,
unsigned long *existing, unsigned long *current)
{
FILE *file;
unsigned long total;
unsigned long file_checksum, checklen;
static char buffer[MAXLENGTH], *endbuffer, *p;
char *checkstring;
endbuffer = &buffer[MAXLENGTH - 1];
if ((file = fopen(config->forward_name, "r")) == NULL)
return (NIL);
checkstring = "# END FILTER FILE. CHECKSUM=";
checklen = strlen(checkstring);
file_checksum = 0;
total = 0;
while (fgets(buffer, MAXLENGTH, file)) {
if (buffer[0] == '#') {
if (strncmp(buffer, checkstring, checklen) == 0) {
p = buffer + strlen(checkstring);
while (*p != '\0' && !Uisdigit(*p))
p++;
if (*p != '\0')
sscanf(p, "%lu", &file_checksum);
}
} else {
*endbuffer = '\0';
total += checksum_hash_line(buffer, MAXLENGTH);
total %= (1024 * 1024); /* Cap values to < 10^6 */
}
}
fclose(file);
*existing = file_checksum;
*current = total;
return (T);
}
/* checksum_generate() ****************************************************
*
* Generate checksum value for a file
* Name of file to checksum
*
* Returns: T => Was able to checksum .forward file
*************************************************************************/
BOOL checksum_generate(char *name)
{
FILE *file;
unsigned long total;
static char buffer[MAXLENGTH], *endbuffer;
endbuffer = &buffer[MAXLENGTH - 1];
if ((file = fopen(name, "r")) == NULL)
return (NIL);
total = 0;
while (fgets(buffer, MAXLENGTH, file)) {
if (buffer[0] == '#')
continue;
*endbuffer = '\0';
total += checksum_hash_line(buffer, MAXLENGTH);
total %= (1024 * 1024); /* Cap values to < 10^6 */
}
fclose(file);
if ((file = fopen(name, "a")) == NULL)
return (NIL);
fprintf(file, "# END FILTER FILE. CHECKSUM=%lu\n", total);
fclose(file);
return (T);
}
syntax highlighted by Code2HTML, v. 0.9.1