new modules soundex.c and environment.c
diff --git a/Modules/Setup.in b/Modules/Setup.in
index b11c192..af9b1dc 100644
--- a/Modules/Setup.in
+++ b/Modules/Setup.in
@@ -272,5 +272,12 @@
 #gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
 
 
+# Andy Bensky's "environment" module (contains putenv())
+#environment environment.c
+
+# David Wayne Williams' soundex module
+#soundex soundex.c
+
+
 # Example -- included for reference only:
 # xx xxmodule.c
diff --git a/Modules/environment.c b/Modules/environment.c
new file mode 100644
index 0000000..977e917
--- /dev/null
+++ b/Modules/environment.c
@@ -0,0 +1,104 @@
+/*
+# Copyright 1995, InfoSeek Corporation 
+# All rights reserved.
+# Written by Andy Bensky
+#
+# Permission to use, copy, modify, and distribute this Python software
+# and its associated documentation for any purpose (subject to the
+# restriction in the following sentence) without fee is hereby granted,
+# provided that the above copyright notice appears in all copies, and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of InfoSeek not be used in
+# advertising or publicity pertaining to distribution of the software
+# without specific, prior written permission.  This permission is
+# explicitly restricted to the copying and modification of the software
+# to remain in Python, compiled Python, or other languages (such as C)
+# wherein the modified or derived code is exclusively imported into a
+# Python module.
+# 
+# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
+# DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, 
+# EVEN IF INFOSEEK SHALL HAVE BEEN MADE AWARE OF THE POSSIBILITY OF SUCH
+# DAMAGES.
+*/
+
+/* Hooks to call the Unix putenv() to modify the environment
+*/
+
+#include "allobjects.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+ 
+/* Error conditions that can be raised */
+ 
+/* Headers for functions accessible from Python as module methods */
+static object *put_environ( object *self, object *args );
+ 
+static struct methodlist environ_methods[] = {
+        {"putenv", put_environ},
+        {NULL, NULL}
+};
+ 
+ 
+/* 
+ * Name: initenvironment
+ * Description: 
+ *     Initialzation function that Python will use to establish callbacks to
+ * the methods of this module.
+ * 
+ * Returns: 
+ *     void  - 
+ * 
+ * Notes: 
+ */ 
+void initenvironment()
+{
+	object *m, *d;
+
+	m = initmodule("environment", environ_methods);
+	d = getmoduledict(m);
+}
+   
+/* 
+ * Name: put_environ
+ * Description: 
+ * accepts 2 string objects as arguments and forms a string of the
+ * form string1=string2 that can be passed to the putenv() system call.
+ *
+ * Returns: 
+ *      None object if successfull, otherwise raises a SystemError exception
+ *
+ * 
+ * Notes: 
+ */ 
+static object *put_environ( object *self, object *args )
+{
+        char *string1, *string2;
+        char *set_str;
+        object *return_object = None;
+ 
+        if (args && getargs(args, "(ss)", &string1, &string2))
+        {
+            set_str = malloc(strlen(string1) + strlen(string2) + 2);
+            assert( set_str );
+            (void) sprintf(set_str, "%s=%s", string1, string2);
+            if ( putenv( set_str ) )
+            {
+                err_setstr(SystemError, "Error in system putenv call.");
+                return_object = 0;
+            }
+        }
+        else
+        {
+                err_setstr(TypeError, "Usage: putenv(string1, string2)");
+                return_object = 0;
+        }
+ 
+        return( return_object );
+}
diff --git a/Modules/soundex.c b/Modules/soundex.c
new file mode 100644
index 0000000..b481e1c
--- /dev/null
+++ b/Modules/soundex.c
@@ -0,0 +1,141 @@
+/*
+  $Header$
+  
+  Perform soundex comparisons on strings.
+
+  Soundex is an algorithm that hashes English strings into numerical value.
+  Strings that sound the same are hashed to the same value.  This allows 
+  for non-literal string matching.
+
+  From: David Wayne Williams <dwwillia@iucf.indiana.edu>
+*/
+
+#include <string.h>
+#include <ctype.h>
+#include "Python.h"
+
+void soundex_hash(char *str, char *result)
+{
+    char *sptr = str;           /* pointer into str */
+    char *rptr = result;        /* pointer into result */
+    
+    if(*str == NULL)
+    {
+        strcpy(result,"000000");
+        return;
+    }
+            
+    /*  Preserve the first character of the input string.
+     */
+    *(rptr++) = toupper(*(sptr++));
+    
+    /* Translate the rest of the input string into result.  The following
+       transformations are used:
+
+       1) All vowles, W, and H, are skipped.
+
+       2) BFPV = 1
+          CGJKQSXZ = 2
+          DT = 3
+          L = 4
+          MN = 5
+
+       3) Only translate the first of adjacent equal translations.  I.E.
+          remove duplicate digits.
+    */
+
+    for(;(rptr - result) < 6 &&  *sptr != NULL;sptr++)
+    {
+        switch (toupper(*sptr))
+        {
+        case 'W':
+        case 'H':
+        case 'A':
+        case 'I':
+        case 'O':
+        case 'U':
+        case 'Y':
+            break;
+        case 'B':
+        case 'F':
+        case 'P':
+        case 'V':
+            if(*(rptr - 1) != '1')
+                *(rptr++) = '1';
+            break;
+        case 'C':
+        case 'G':
+        case 'J':
+        case 'K':
+        case 'Q':
+        case 'S':
+        case 'X':
+        case 'Z':
+            if(*(rptr - 1) != '2')
+                *(rptr++) = '2';
+            break;
+        case 'D':
+        case 'T':
+            if(*(rptr - 1) != '3')
+                *(rptr++) = '3';
+            break;
+        case 'L':
+            if(*(rptr - 1) != '4')
+                *(rptr++) = '4';
+            break;
+        case 'M':
+        case 'N':
+            if(*(rptr - 1) != '5')
+                *(rptr++) = '5';
+            break;
+        default:
+            break;
+        }
+    }
+
+    /* Pad 0's on right side of string out to 6 characters.
+     */
+    for(; rptr < result + 6; rptr++)
+        *rptr = '0';
+
+    /* Terminate the result string.
+     */
+    *(result + 6) = NULL;
+}
+
+
+static PyObject *
+sound_similar(PyObject *self, PyObject *args)
+{
+    char *str1, *str2;
+    int return_value;
+    char res1[7], res2[7];
+    
+    if(!PyArg_ParseTuple(args, "ss", &str1, &str2))
+        return NULL;
+
+    soundex_hash(str1, res1);
+    soundex_hash(str2, res2);
+
+    if(!strcmp(res1,res2))
+        return Py_BuildValue("i",1);
+    else
+        return Py_BuildValue("i",0);
+}
+
+/* Python Method Table.
+ */
+static PyMethodDef SoundexMethods[] =
+{
+    {"sound_similar", sound_similar, 1},
+    {NULL, NULL }               /* sentinel */
+};
+
+
+/* Register the method table.
+ */
+void
+initsoundex()
+{
+    (void) Py_InitModule("soundex",SoundexMethods);
+}