Hi,
I am trying to implement an MD5 checksum function using an UDF call to
C wrapper returning the MD5 checksum. I've downloaded a free (LGPL)
implementation in C of the MD5 algorithm from
http://xyssl.org/code/source/md5/. With help from our friends over at
comp.lang.c, I've managed to compile, link and run the code. However,
when I call it from DB2, I can invoke it once only.
I suspect the error has to do with freeing of memory, but my limited C
skills keep me from understanding why.
// md5.c
#include "md5.h"
#include <sqludf.h>
#include <stdio.h>
#include <string.h>
void md5 (
// input parameters
SQLUDF_VARCHAR_FBD *input,
// output
SQLUDF_VARCHAR *output,
// null indicators
SQLUDF_NULLIND *inputNull_ind,
SQLUDF_NULLIND *outputNull_ind,
SQLUDF_TRAIL_ARGS
)
{
int i;
unsigned char *uc_tmp;
char c[10];
char md5ascii[128];
if (*inputNull_ind == -1)
{
*outputNull_ind = -1;
}
else
{
// Compute binary checksum
md5_csum( (uchar *) input, input->length, uc_tmp );
// Convert binary checksum to ascii
memset(md5ascii, 0, sizeof(md5ascii));
for (i = 0; i < 16; i++) {
snprintf(c, sizeof(c), "%0x", uc_tmp[i]);
strncat(md5ascii, c, sizeof(md5ascii) - 1);
}
// Copy ascii checksum to output pointer
strcpy(output, md5ascii);
*outputNull_ind = 0;
return;
}
}
$ # compile, link and install
$ gcc -c -o md5.o -I../md5_xyssl -I/home/db2inst1/sqllib/include
md5.c ../md5_xyssl/md5.c -D_REENTRANT
$ gcc -o md5 -shared -fpic md5.o
$ sudo su
# cp md5 /home/db2inst1/sqllib/function
-- md5.sql
DROP FUNCTION MD5;
CREATE FUNCTION MD5
(HASH VARCHAR(32000))
RETURNS VARCHAR(32)
SPECIFIC MD5
EXTERNAL NAME 'md5!md5'
NOT FENCED
RETURNS NULL ON NULL INPUT
DETERMINISTIC
NO SQL
NO EXTERNAL ACTION
LANGUAGE C
PARAMETER STYLE SQL
ALLOW PARALLEL;
$ db2 "select FIRSTNME, MD5(FIRSTNME) AS MD5SUM from employee fetch
first 5 rows only"
FIRSTNME MD5SUM
------------ --------------------------------
CHRISTINE 86b83514912a7ff1386e522c5bfd7330
MICHAEL cce39636156586527630722a64883c7
SALLY 82ac3ac8667126e51494af39a97d1
JOHN c4baad2cbe78654d7902c726be7e2
IRVING b3c9701751a843882dde77fa165bb7f6
5 record(s) selected.
$ db2 "select FIRSTNME, MD5(FIRSTNME) AS MD5SUM from employee fetch
first 5 rows only"
FIRSTNME MD5SUM
------------ --------------------------------
SQL0444N Routine "DB2INST1.MD5" (specific name "MD5") is implemented
with
code in library or path "??p Q?C?-?w? [??qllib/function/md5", function
"md5"
which cannot be accessed. Reason code: "4". SQLSTATE=42724
--
Serman D.