diff -Nur eggdrop1.1.5/Makefile.in eggdrop1.1.5+sha/Makefile.in
--- eggdrop1.1.5/Makefile.in	Sun Jun 29 14:21:19 1997
+++ eggdrop1.1.5+sha/Makefile.in	Wed May 23 17:34:39 2001
@@ -112,7 +112,7 @@
 	dcc.o dccutil.o gotdcc.o hash.o main.o\
 	match.o mem.o misc.o mode.o msgcmds.o msgnotice.o net.o notes.o\
 	tcl.o tclchan.o tcldcc.o tclhash.o tclmisc.o tcluser.o userrec.o\
-	users.o
+	users.o sha.o shahl.o
 
 GMAKE_SHLIB = ${MAKE} 'CC=${SHLIB_CC}' 'LD=${SHLIB_LD}' 'OBJS=${OBJS}'\
 'STRIP=${SHLIB_STRIP}' 'CFLAGS=${CFLAGS} -DMODULES' 'XLIBS=@TCL_LIBS@ @LIBS@'
diff -Nur eggdrop1.1.5/src/Makefile eggdrop1.1.5+sha/src/Makefile
--- eggdrop1.1.5/src/Makefile	Sun Jun 29 13:40:10 1997
+++ eggdrop1.1.5+sha/src/Makefile	Wed May 23 17:39:51 2001
@@ -120,6 +120,13 @@
 users.o: users.c
 	${CC} ${CFLAGS} users.c
 
+sha.o: sha.c
+	${CC} ${CFLAGS} sha.c
+
+shahl.o: shahl.c
+	${CC} ${CFLAGS} shahl.c
+
+
 # I orginially had this in another file, but some lame make's can't cope :/ 
 botcmd.o: \
    eggdrop.h \
diff -Nur eggdrop1.1.5/src/environ.h eggdrop1.1.5+sha/src/environ.h
--- eggdrop1.1.5/src/environ.h	Wed Dec 31 19:00:00 1969
+++ eggdrop1.1.5+sha/src/environ.h	Wed May 23 17:40:05 2001
@@ -0,0 +1,240 @@
+#define SUN
+/* *****************************************************************
+ * environ.h
+ *   Public domain
+ *
+ * --ABSTRACT-- environ.h
+ * These are the definitions that define the environment that
+ * the compile is happening in.
+ *
+ * --KEYWORDS-- environ.h
+ * Portability, standards
+ * 
+ * --CONTENTS-- environ.h
+ * Date, Department, Author
+ *    26APR1991, John Halleck
+ * Revision history
+ *    For each revision: Date, change summary, authorizing document,
+ *    change department, section, author
+ *    26APR1991, Initial Creation, John Halleck
+ *    30APR1991, Added Ultrix.
+ *    18OCT1994, Fixed some of the PC defs.
+ *    17NOV1994, Added HP.
+ *    19dec1994, added NOVOID
+ *    20apr1994, added PROTOTYPES, ARGCARGV,
+ *               in addition to NOPROTOTYPES
+ * Unit purpose
+ *    (What does this do?)
+ *    Any routines that use non-standard features use these defines
+ *    to turn them on.  A unit that does not include this should be
+ *    standard.  One that includes this is standard if none of the
+ *    tags are uncommented.
+ * External Units accessed
+ *    Name, purpose, access summary
+ *    [None]
+ * Exceptions propagated by this unit
+ *    [None]
+ * Machine-dependencies
+ *    Access type, purpose, and justification
+ *    [None]
+ * Compiler-dependencies
+ *    Everything here is machine specific...
+ ********************************************************************
+ */
+#ifndef ENVIRONMENT
+#define ENVIRONMENT
+
+/* There are more tags here than may be used in the project that you
+ * are compiling.   Rather than have such a file for each project,
+ * all of my projects make use of this same one, and a tag may be
+ * here if it is used in ANY project that I have.
+ */
+
+/* The defaults here are as generic as I can make them.  However, you
+ * should set your machine to make sure that things are correct.
+ * 
+ * *********************************************************************
+ * You should check that the BIT8, BIT16, and BIT32 types are correct. *
+ ***********************************************************************
+ */
+
+/* machine   ---------------------------------------------------
+ * If this is being compiled for a Macintosh, define the macro as
+ * one of the following
+ *
+ *  #define MACINTOSH
+ *     (Generic Mac)
+ *  (No others yet used)
+ */
+
+/* or -----------------------------------------------------------
+ * if this is being compiled for a PC define the macro as
+ * one of the following
+ *  #define PC
+ *     (Generic PC)
+ *  #define PC SPERRY
+ *     (Sperry's PC)
+ */
+
+/* or -----------------------------------------------------------
+ * if this is being compiled for a Sun workstation
+ *  #define SUN
+ *      (Generic sun)
+ *  #define SUN 3
+ *      A sun 3/xxx
+ *  #define SUN 4
+ *      A sun 4 (including SparcStations)
+ *  #define SUN SOLARIS
+ */
+
+/* or ----------------------------------------------------------- 
+ * if this is being compiled for a Univac 1100 series machine.
+ * #define UNIVAC
+ *      (Generic Univac)
+ */
+
+/* or -----------------------------------------------------------
+ * if this is being compiled for a DEC machine.
+ * #define DEC
+ *      (Generic Univac)
+ * #define DEC PDP11
+ * #define DEC PDP10
+ * #define DEC PDP20
+ * #define DEC ALPHA
+ * #define DEC VAX
+ */
+ 
+/* OR ----------------------------------------------------------- 
+ * If this is being compiled for an HP machine.
+ * #define HP
+ *      (Generic HP, whatever that is)
+ * #define HP 9000
+ */
+
+/* end machines  ------------------------------------------------ */
+
+
+/* ***** PURE derivation ******  */
+/* These define the following:
+ * BITS8  unsigned 8 bit quantity.
+ * BITS16 unsigned 16 bit quantity.
+ * BITS32 unsigned 32 bit quantity.
+ * BITS32_GREATERTHAN_32  If BITS32 is in a word physically bigger 
+ *                        than 32 bits long. (As on a 36 bit word machine)
+ *
+ * NOPROTOTYPES  If the machine does not support ANSI C prototypes.
+ *   PROTOTYPES  If the machine does     support ANSI C prototypes.
+ * NOARGCARGV    if the machine does not support UNIX style argc, argv.
+ *   ARGCARGV    if the machine does     support UNIX style argc, argv.
+ *
+ * NOCONST       if the machine does not support the  const    qualifier
+ * NOVOLATILE    if the machine does not support the  volatile qualifier
+ * NOVOID        if the machine does not support the  void     data type.
+ */
+
+#ifdef PC
+#define BITS8  unsigned char
+#define BITS16 unsigned short
+#define BITS32 unsigned long
+#define ARGCARGV
+#define PROTOTYPES
+#endif
+
+#ifdef UNIVAC
+#define BITS8  unsigned char
+#define BITS16 unsigned short
+#define BITS32 unsigned long
+#define BIT32_GREATERTHAN_32
+#define ARGCARGV
+#define NOPROTOTYPES
+#endif /* UNIVAC */
+
+#ifdef SUN
+#define BITS8  unsigned char
+#define BITS16 unsigned short
+#define BITS32 unsigned long
+#define ARGCARGV
+#define NOPROTOTYPES
+#endif /* SUN */
+
+#ifdef DEC
+/* ??? */
+#endif
+#if DEC == VAX
+#define VMS
+/* Somebody needs to fill these in. */
+/* ???????? */
+#endif
+#if DEC == ALPHA
+/* ??? */
+#endif
+#endif
+
+#ifdef MACINTOSH
+#define BITS8  unsigned char
+#define BITS16 unsigned short
+#define BITS32 unsigned long
+#define NOARGCARGV
+#define PROTOTYPES
+#endif
+
+#ifdef HP
+#if HP == 9000
+#define HPUX
+#endif
+#endif
+
+#ifdef HPUX
+#define BITS8  unsigned char
+#define BITS16 unsigned short
+#define BITS32 unsigned long
+#define ARGCARGV
+#define PROTOTYPES
+#endif
+
+/* ----------------- Pure defaults --------------------- */
+#ifndef BITS8
+#define BITS8  unsigned char
+#endif
+#ifndef BITS16
+#define BITS16 unsigned int
+#endif
+#ifndef BITS32
+#define BITS32 unsigned long
+#endif
+
+#ifndef PROTOTYPES
+#define NOPROTOTYPES
+#endif
+
+#ifndef ARGCARGV
+#define NOARGCARGV
+#endif
+
+/* ---------------- Housekeeping -------------------------- */
+
+#ifdef  NOVOID
+typedef int void; /* we have to declare it as something */
+#endif
+
+/* We know how to do standard C */
+#ifndef _STDC_
+#define NOCONST
+#define NOVOLATILE
+#else
+#ifdef NOPROTOTYPES
+#undef NOPROTOTYPES
+#define  PROTOTYPES
+#endif
+#endif
+
+#ifdef  NOCONST
+#define const
+#endif
+
+#ifdef NOVOLATILE
+#define volatile
+#endif
+
+/* ENVIRONMENT */
+/* end environ.h **************************************************** */
diff -Nur eggdrop1.1.5/src/main.c eggdrop1.1.5+sha/src/main.c
--- eggdrop1.1.5/src/main.c	Sun Jun 29 14:18:07 1997
+++ eggdrop1.1.5+sha/src/main.c	Wed May 23 18:49:18 2001
@@ -1201,7 +1201,7 @@
    }
 
    /* --- PATCH INFO GOES HERE --- */
-   
+   PATCH("sha1.0");
    /* --- END OF PATCH INFO --- */
 
    /* version info! */
diff -Nur eggdrop1.1.5/src/sha.c eggdrop1.1.5+sha/src/sha.c
--- eggdrop1.1.5/src/sha.c	Wed Dec 31 19:00:00 1969
+++ eggdrop1.1.5+sha/src/sha.c	Wed May 23 17:40:09 2001
@@ -0,0 +1,379 @@
+/* *****************************************************************
+ * sha.c
+ * (C) Copyright 1994 John Halleck
+ * All rights reserved
+ *
+ * --ABSTRACT-- sha.c
+ * This implements the "Secure Hash Algorithm" as per the original
+ * NIST specs, with the latest NIST version as an option.
+ *
+ * --KEYWORDS-- sha.c
+ *
+ * --CONTENTS-- sha.c
+ * Date, Department, Author
+ *   20may1994, John Halleck
+ * Revision history
+ *   For each revision: Date, change summary, authorizing document,
+ *   change department, section, author
+ *    3nov1999, Corrected padding bug.
+ *   20apr1995, change to default context option, John Halleck.
+ *   19nov1994, portablility changes, output string code.
+ *    1aug1994, Changes per NIST
+ *   20may1994, Initial Creation, John Halleck
+ * Unit purpose
+ *   (What does this do?)
+ *   Implements the "Secure Hash Algorithm" as proposed by NSA
+ * Unit function
+ *   (How does it do it?)
+ *   Straight forward reduction of the spec to code.
+ * External Units accessed
+ *   Name, purpose, access summary
+ * Exceptions propagated by this unit
+ *   [None]
+ * Input Output
+ *   Device name, Access type, Access purpose, access summary
+ *   [None]
+ * Machine-dependencies
+ *   Access type, purpose, and justification
+ *   Assumes a 32 bit word is availiable.
+ * Compiler-dependencies
+ *   [None]
+ *******************************************************************
+ */
+
+#include <string.h>
+#include "environ.h"
+
+/* This code is independent of the byte order of the
+ * underlying machine.  (Bigendian and Littleendian were
+ * bad enough, but when I started to deal with machines like
+ * the PDP-11 getting the order right became difficult without
+ * a redesign...
+ */
+ 
+/* Public part of this unit. */
+#include "sha.h"
+
+#ifndef NOPROTOTYPES
+/* Private part of this unit */
+void shapad        (sha_context_ptr context);
+void shaTransform  (sha_context_ptr context);
+void shaTransformCanned                     (void);
+#endif
+
+
+#define SHF_LENGTH_PAD  8
+#define SHF_PAD_WORDS 2
+/* Part of the padding needs to be message length (2  4 byte words) */
+#define SHF_PADDING (SHF_BLOCKSIZE - SHF_LENGTH_PAD)
+/* Remainder of block to be padded */
+
+/* We have to exercise special care on machines with a natural
+ * wordlength >32 characters that we do masking properly
+ */
+#ifdef BITS32_GREATERTHAN_32
+#define MASK32 & 0xFFFFFFFF
+#define MASK8 & 0xFF
+#else
+#define MASK32
+#define MASK8
+#endif
+
+int debugi; /* DEBUG */
+
+static sha_context canned_context;
+/* Place for contextless calls to have context. */
+
+
+
+/* Implementation */
+
+#ifdef NOPROTOTYPES
+void shaInit (context, version)
+sha_context_ptr context;
+int version;
+{
+#else
+void shaInit (sha_context_ptr context, int version) {
+#endif
+ int loopindex;
+
+ if (!context) context = &canned_context;
+ 
+ /* Set initial values */
+ context->digest[0] = 0x67452301L;
+ context->digest[1] = 0xEFCDAB89L;
+ context->digest[2] = 0x98BADCFEL;
+ context->digest[3] = 0x10325476L;
+ context->digest[4] = 0xC3D2E1F0L;
+
+ /* Initialize bit count */
+ context->countLo = 0L;
+ context->countHi = 0L;
+ 
+ /* Initialize buffer to empty. */
+ context->thisword = 0;
+ context->thisbyte = 0;
+ 
+ /* Zero out data */
+ for (loopindex=0;loopindex<SHF_BLOCKWORDSIZE;loopindex++)
+     context->data[loopindex] = 0;
+
+ /* What sort of SHA are we doing? */
+ context->kind = version;
+ 
+}
+
+/* 
+**************************************************************** 
+*/
+
+/* Rotate Left n bits (32 bit) */
+#define S(n,X) (((X)<<(n)) | ((X)>>(32-(n))))
+
+#ifdef NOPROTOTYPES
+static void shaTransform (context)
+sha_context_ptr context;
+{
+#else
+static void shaTransform (sha_context_ptr context) {
+#endif
+
+ BITS32 W[80], temp;  int i;
+
+/* A buffer of 5 32-bit words */
+BITS32 A, B, C, D, E;
+
+#define DG   context->digest
+
+ if (!context) context = &canned_context;
+
+/* Get digest */
+ A = DG[0]; B = DG[1]; C = DG[2]; D = DG[3]; E = DG[4];
+
+ /* Copy the data buffer into the work buffer */
+ for (i=0; i<SHF_BLOCKWORDSIZE; i++)
+     {W[i] = context->data[i];context->data[i] = 0;}
+ 
+/* Expand the 16 words into the SHF_BLOCKSIZE temporary data words */
+ for (i=16; i<80; i++) {
+     W[i] = W[i-3]^W[i-8]^W[i-14]^W[i-16];
+     if (context->kind) W[i] = S(1,W[i]);
+ }
+ 
+/* Guts (four sub-rounds) */
+#define PRE  temp = W[i] + S(5,A) + E + 
+#define POST ; E = D; D = C; C = S(30,B); B = A; A = temp;
+ for (i= 0; i<20; i++) {PRE 0x5A827999L + (( B & C ) | (~B & D))  POST}
+ for (i=20; i<40; i++) {PRE 0x6ED9EBA1L + (B^C^D)                 POST}
+ for (i=40; i<60; i++) {PRE 0x8F1BBCDCL + ((B&C) | (B&D) | (C&D)) POST}
+ for (i=60; i<80; i++) {PRE 0xCA62C1D6L + (B^C^D)                 POST}
+
+/* Update digest */
+ DG[0] += A; DG[1] += B; DG[2] += C; DG[3] += D; DG[4] += E;
+
+#if BITS32_GREATERTHAN_32
+ DG[0] &= 0xFFFFFFFF;
+ DG[1] &= 0xFFFFFFFF;
+ DG[2] &= 0xFFFFFFFF;
+ DG[3] &= 0xFFFFFFFF;
+ DG[4] &= 0xFFFFFFFF;
+#endif
+
+/* Block is now empty */
+ context->thisword = 0;
+ context->thisbyte = 0;
+}
+
+
+/* ******************************* */
+
+#ifdef NOPROTOTYPES
+void shaUpdate (context, buffer, count)
+sha_context_ptr context;
+BITS8 *buffer;
+int count;
+{
+#else
+void shaUpdate (sha_context_ptr context, BITS8 *buffer, int count) {
+#endif
+
+ BITS32 thebits; /* current bit pattern being processed */
+ int theword; /* Which word in the buffer we are dealing with. */
+ int i;
+ 
+ if (!context) context = &canned_context;
+
+ /* Add a potentially 32 bit count to the two word count */
+ context->countHi += count >> 29;           /* handle count > 2**29 */
+ context->countLo += count & 0x1FFFFFFF;    /* Handle count <=2**29 */
+ context->countHi += context->countLo >> 29;/* Handle carry */
+ context->countLo &= 0x1FFFFFFF;            /* Clear carry  */
+
+ theword = context->thisword;
+ thebits = context->data[theword];
+
+ while (count--) {
+   thebits = (thebits << 8) | *buffer++;
+   if (++context->thisbyte >= 4) {
+      context->data[theword++] = thebits; thebits = 0;
+      if (theword >= SHF_BLOCKWORDSIZE) { 
+         shaTransform (context);
+         theword = 0;
+      }
+      context->thisbyte = 0;
+   }
+ }
+ context->data[theword] = thebits;
+ context->thisword = theword;
+
+ }
+/* ************************************ */
+#ifdef NOPROTOTYPES
+void shaStrUpdate  (context, input)
+sha_context_ptr context;
+char *input;
+#else
+void shaStrUpdate  (sha_context_ptr context, char *input)
+#endif
+{shaUpdate (context, (BITS8 *)input, strlen(input));}
+
+/* ************************************ */
+/* Pad out a block. */
+
+#ifdef NOPROTOTYPES
+static void shapad(context)
+sha_context_ptr context;
+{
+#else
+static void shapad(sha_context_ptr context) {
+#endif
+  int loopindex;
+
+  if (!context) context = &canned_context;
+
+  context->data[context->thisword]<<=8;
+  context->data[context->thisword] |= 0x80;
+  /* pad out the rest of this word */
+  switch (context->thisbyte) {
+    case 3:                                      ;break;
+    case 2: context->data[context->thisword]<<= 8;break;
+    case 1: context->data[context->thisword]<<=16;break;
+    case 0: context->data[context->thisword]<<=24;break;
+  }
+
+  /* and then the rest of the words in the block */
+  for (loopindex=context->thisword + 1; loopindex < SHF_BLOCKWORDSIZE;loopindex++)
+     context->data[loopindex] = 0;
+
+  /* And note it is now empty */
+  context->thisword = 0;  context->thisbyte = 0;
+}
+/* ************************************ */
+/* Convert a word digest to bytes, in a byte order independent manner */
+
+#ifdef NOPROTOTYPES
+void shaBytes (context, adigest)
+sha_context_ptr context;
+sha_digest adigest;
+{
+#else 
+void shaBytes (sha_context_ptr context, sha_digest adigest) {
+#endif
+int loopindex;
+
+ if (!context) context = &canned_context;
+
+ for (loopindex=0;loopindex<SHF_DIGESTWORDSIZE;loopindex++) {
+     *adigest++ = (BITS8) (context->digest[loopindex] >> 24   MASK8);
+     *adigest++ = (BITS8) (context->digest[loopindex] >> 16  & (BITS32) 0xFF);
+     *adigest++ = (BITS8) (context->digest[loopindex] >>  8  & (BITS32) 0xFF);
+     *adigest++ = (BITS8) (context->digest[loopindex]        & (BITS32) 0xFF);
+ }
+
+}
+
+/* ************************************ */
+#ifdef NOPROTOTYPES
+void shaString (adigest, outputstring)
+sha_digest adigest;
+char *outputstring;
+{
+#else
+void shaString (sha_digest adigest, char *outputstring) {
+#endif
+  char output [17];
+  int loop; int abyte;
+
+  strcpy (output, "0123456789ABCDEF");
+
+  for (loop = 0; loop < SHF_DIGESTSIZE; loop++) {
+     abyte = *adigest++;
+     *outputstring++ = output [ (abyte >> 4) & 0xF ];
+     *outputstring++ = output [  abyte       & 0xF ];
+  }
+  *outputstring = 0;
+}
+/* ************************************ */
+
+#ifdef NOPROTOTYPES
+void shaFinal(context, adigest)
+sha_context_ptr context;
+sha_digest adigest;
+{
+#else
+void shaFinal (sha_context_ptr context, sha_digest adigest) {
+#endif
+ int loopindex; int bytesused;
+
+ if (!context) context = &canned_context;
+
+ /* bytes used in the buffer */
+ bytesused = context->thisword * 4 + context->thisbyte + 2;
+   /* +1 for un zerobasing, +1 for the pad character we're about to do */
+ 
+ /* Pad, but with the convention that the 0 pad starts with a single */
+ /* one bit. */
+ shapad(context);
+
+ /* if we don't have room for the message size, then start a new block */
+ if (bytesused > (SHF_BLOCKSIZE - SHF_LENGTH_PAD)) {
+    shaTransform(context);
+    for (loopindex=0; loopindex<(SHF_BLOCKWORDSIZE-SHF_PAD_WORDS); loopindex++) 
+        context->data[loopindex] = 0;
+    context->thisword = SHF_BLOCKWORDSIZE;
+    context->thisbyte = 0;
+ }
+
+ /* Append length in bits, and transform */
+ context->data[14] = context->countHi;
+ context->data[15] = context->countLo<<3; /* We keep it as a byte count */
+ shaTransform (context);
+
+ /* get the digest out to the user. */
+ shaBytes (context, adigest);
+
+} /* end routine shaFinal */
+
+
+/* ************************************************************ */
+
+#ifdef NOPROTOTYPES
+void shaHash (version, buffer, count, adigest)
+int version;
+BITS8 *buffer;
+int count;
+sha_digest adigest;
+{
+#else
+void shaHash (int version, BITS8 *buffer, int count, sha_digest adigest) {
+#endif
+ sha_context example;
+
+ shaInit   (&example, version);
+ shaUpdate (&example, buffer, count);
+ shaFinal  (&example, adigest);
+
+}
+
+/* end sha.c **************************************************** */
diff -Nur eggdrop1.1.5/src/sha.h eggdrop1.1.5+sha/src/sha.h
--- eggdrop1.1.5/src/sha.h	Wed Dec 31 19:00:00 1969
+++ eggdrop1.1.5+sha/src/sha.h	Wed May 23 17:40:12 2001
@@ -0,0 +1,123 @@
+/* *****************************************************************
+ * sha.h
+ * © Copyright 1994 John Halleck
+ * All rights reserved
+ *
+ * --ABSTRACT-- sha.h
+ * This implements the "Secure Hash Algorithm" as per the original
+ * NIST specs, with the latest NIST version as an option.
+ *
+ * --KEYWORDS-- sha.h
+ *
+ * --CONTENTS-- sha.h
+ * Date, Department, Author
+ *    20may1994, John Halleck
+ * Revision history
+ *    For each revision: Date, change summary, authorizing document,
+ *    change department, section, author
+ *    20may1994, Initial Creation, John Halleck
+ *     1aug1994, Changes per NIST
+ *    19nov1994, portablility changes, output string code.
+ *   20apr1995, change to default context option, John Halleck.
+ * Unit purpose
+ *    (What does this do?)
+ *    Secure hash function with the NIST modifications, and renamed
+ *    routines.
+ * External Units accessed
+ *    Name, purpose, access summary
+ *    [None]
+ * Exceptions propagated by this unit
+ *    [None]
+ * Machine-dependencies
+ *    Access type, purpose, and justification
+ *    Assumes there is a 32 bit word availiable on the machine.
+ * Compiler-dependencies
+ *    [None]
+ ********************************************************************
+ */
+
+/* Random note: This standard was originally proposed to provide a hash function
+ * for the Digital Signature Standard that was proposed in August 1991 
+ */
+ 
+#ifndef SHF
+#define SHF
+
+#include "environ.h"
+/* Defines common to everything */
+
+#define SHF_DIGESTSIZE 20
+/* Put out a digest of this size in bytes */
+#define SHF_DIGESTWORDSIZE 5
+/* and words */
+
+#define SHF_BLOCKSIZE  64
+#define SHF_BLOCKWORDSIZE 16
+/* Process messages in this block size */
+
+/* Structure for storing SHF info */
+
+typedef BITS32 shadigest[SHF_DIGESTWORDSIZE];
+typedef BITS8  sha_digest[SHF_DIGESTSIZE];
+
+typedef struct {
+  BITS32    data [SHF_BLOCKWORDSIZE];     /* SHS data buffer */
+  BITS32    countLo;       /* Count (64 bits in              */
+  BITS32    countHi;       /* 2 32 bit words)                */
+  shadigest digest;        /* Message digest                 */
+  int       kind;          /* Which type of SHA?             */
+  int       thisword;      /* Which word are we processing?  */
+  int       thisbyte;      /* Which byte in that word?       */
+} sha_context, *sha_context_ptr;
+
+#ifndef NOPROTOTYPES
+
+/* These routines all take a context, so that multiple streams can be
+ * handled.  If you pass NULL, then a single package wide canned context
+ * will be used.
+ */
+
+/* Initialize a stream */
+void shaInit       (sha_context_ptr context, int version);
+/* Version 0 - Original NIST version (Obsolete) */
+/*             (30 January 1995) */
+/* Version 1 - lastest NIST modifications    */
+
+/* Add a buffer's worth of characters to the current hash. */
+void shaUpdate     (sha_context_ptr context, BITS8 *buffer, int count);
+
+/* Add a string's worth of characters to the current hash. */
+void shaStrUpdate  (sha_context_ptr context, char *input);
+
+/* Done, report the final hash. */
+void shaFinal      (sha_context_ptr context, sha_digest adigest);
+
+/* And for all you bit twiddlers out there, the machine independent
+ * Digest to digest string routines.
+ */
+ 
+/* digest from context */
+void shaBytes (sha_context_ptr context, sha_digest adigest);
+/* string from digest */
+void shaString (sha_digest adigest, char *outputstring);
+
+/* hash of a buffer */
+/* This returns directly the SHA digest of the characters in a buffer. */
+void shaHash (int version, BITS8 *buffer, int count, sha_digest adigest);
+
+#else
+
+extern void shaInit            ();
+extern void shaUpdate          ();
+extern void shaStrUpdate       ();
+extern void shaFinal           ();
+extern void shaBytes           ();
+extern void shaString          ();
+extern void shaHash            ();
+
+#endif 
+/* NOPROTOTYPES */
+
+#endif
+/* SHF */
+/* end sha.h ***************************************************** */
diff -Nur eggdrop1.1.5/src/shahl.c eggdrop1.1.5+sha/src/shahl.c
--- eggdrop1.1.5/src/shahl.c	Wed Dec 31 19:00:00 1969
+++ eggdrop1.1.5+sha/src/shahl.c	Wed May 23 17:40:01 2001
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <config.h>
+
+#include "environ.h"
+#include "sha.h"
+/* #include "eggdrop.h"
+*/
+static sha_digest mydigest;
+static sha_context acontext;
+static sha_digest adigest;
+
+                
+char *shaFile(char *filename)
+{
+  FILE *file;
+  int len, loop;
+  char *p;
+  BITS8 buffer[1024];
+  
+  if ((file = fopen (filename, "rb")) == NULL) {
+    return 0;
+  }
+  p=malloc(41);
+  memset(p, 0, 41);                           
+  shaInit   (&acontext, 1);
+                                
+  while (len = fread (buffer, 1, 1024, file))
+    shaUpdate (&acontext, buffer, len);
+  shaFinal  (&acontext, adigest);
+                                                 
+  fclose (file);
+                                                     
+  for (loop=0; loop < SHF_DIGESTSIZE; loop++) {
+    sprintf (p + (loop*2), "%.2x", adigest[loop]);
+  }
+
+  return p;
+} 
+
+char *shaData(const unsigned char *data)
+{
+  char *p;
+  int loop;
+  int pos;
+
+  p=malloc(41);
+  memset(p, 0, 41);
+
+  shaInit   (NULL, 1);
+  shaUpdate (NULL, (BITS8 *) data, strlen (data));
+  shaFinal  (NULL, mydigest);
+
+  pos = 0;
+  for (loop=0; loop < SHF_DIGESTSIZE; loop++) {
+    sprintf (p + (loop*2), "%.2x", mydigest[loop]);
+  }
+  return p;
+}              
diff -Nur eggdrop1.1.5/src/tcl.c eggdrop1.1.5+sha/src/tcl.c
--- eggdrop1.1.5/src/tcl.c	Thu Jun 26 15:57:42 1997
+++ eggdrop1.1.5+sha/src/tcl.c	Wed May 23 17:39:48 2001
@@ -790,6 +790,8 @@
    Q("savechannels", tcl_savechannels);
    Q("loadchannels", tcl_loadchannels);
    Q("isdynamic", tcl_isdynamic);
+   Q("shastring", tcl_shastring);
+   Q("shafile", tcl_shafile);
 #ifndef MODULES
 #ifndef NO_FILE_SYSTEM
    Q("dccsend", tcl_dccsend);
diff -Nur eggdrop1.1.5/src/tclegg.h eggdrop1.1.5+sha/src/tclegg.h
--- eggdrop1.1.5/src/tclegg.h	Sun Jun 29 12:19:27 1997
+++ eggdrop1.1.5+sha/src/tclegg.h	Wed May 23 18:49:08 2001
@@ -161,6 +161,7 @@
 X5(tcl_unshare, tcl_encrypt, tcl_decrypt, tcl_dumpfile, tcl_dccdumpfile);
 X5(tcl_backup, tcl_die, tcl_strftime, tcl_mkdir, tcl_rmdir);
 X(tcl_getflags); X(tcl_setflags); X(tcl_mv); X(tcl_cp);
+X(tcl_shastring); X(tcl_shafile);
 #endif
 
 /* functions definitions moved here from proto.h */
diff -Nur eggdrop1.1.5/src/tclmisc.c eggdrop1.1.5+sha/src/tclmisc.c
--- eggdrop1.1.5/src/tclmisc.c	Sun Jun 29 13:35:01 1997
+++ eggdrop1.1.5+sha/src/tclmisc.c	Wed May 23 17:43:20 2001
@@ -384,6 +384,28 @@
    return TCL_ERROR;
 }
 
+int tcl_shastring STDVAR
+{
+    char *p;
+
+    BADARGS(2, 2, " string");
+    p = shaData(argv[1]);
+    Tcl_AppendResult(irp, p, NULL);
+    if (p != NULL) nfree(p);
+    return TCL_OK;   
+}
+
+int tcl_shafile STDVAR 
+{
+    char *p;
+
+    BADARGS(2, 2, " filename");
+    p = shaFile(argv[1]);
+    Tcl_AppendResult(irp, p, NULL);
+    if (p != NULL) nfree(p);
+    return TCL_OK;
+}
+
 #ifndef NO_FILE_SYSTEM
 #ifndef MODULES
 #include "mod/filesys.mod/tclfiles.c"
