--- /dev/null	Fri Sep 20 17:28:33 2019
+++ Modules/my_mktime.c	Sun Sep  8 20:44:56 2019
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 1987, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Arthur David Olson of the National Cancer Institute.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.  */
+
+/*static char *sccsid = "from: @(#)ctime.c	5.26 (Berkeley) 2/23/91";*/
+/*static char *rcsid = "mktime.c,v 1.1.1.3 1998/11/15 19:23:34 kardel RELEASE_19990228_A";*/
+
+/*
+ * This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)
+ * version.  I modified it slightly to divorce it from the internals of the
+ * ctime library.  Thus this version can't use details of the internal
+ * timezone state file to figure out strange unnormalized struct tm values,
+ * as might result from someone doing date math on the tm struct then passing
+ * it to mktime.
+ *
+ * It just does as well as it can at normalizing the tm input, then does a
+ * binary search of the time space using the system's localtime() function.
+ *
+ * The original binary search was defective in that it didn't consider the
+ * setting of tm_isdst when comparing tm values, causing the search to be
+ * flubbed for times near the dst/standard time changeover.  The original
+ * code seems to make up for this by grubbing through the timezone info
+ * whenever the binary search barfed.  Since I don't have that luxury in
+ * portable code, I have to take care of tm_isdst in the comparison routine.
+ * This requires knowing how many minutes offset dst is from standard time.
+ *
+ * So, if you live somewhere in the world where dst is not 60 minutes offset,
+ * and your vendor doesn't supply mktime(), you'll have to edit this variable
+ * by hand.  Sorry about that.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef DSTMINUTES
+#define DSTMINUTES 60
+#endif
+
+#define FALSE 0
+#define TRUE 1
+
+/* some constants from tzfile.h */
+#define SECSPERMIN      60
+#define MINSPERHOUR     60
+#define HOURSPERDAY     24
+#define DAYSPERWEEK     7
+#define DAYSPERNYEAR    365
+#define DAYSPERLYEAR    366
+#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY      ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR     12
+#define TM_YEAR_BASE    1900
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <time.h>
+
+extern time_t	time();
+
+static int	mon_lengths[2][MONSPERYEAR] = {
+	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static int	year_lengths[2] = {
+	DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+**	The "best" way to do mktime I think is based on an idea of Bob
+**	Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
+**	It does a binary search of the time_t space.  Since time_t's are
+**	just 32 bits, its a max of 32 iterations (even at 64 bits it
+**	would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG	(-1)
+#endif /* !defined WRONG */
+
+static int leap_years_to_end ( int tm_year ) {
+    int leap_years = 0;
+
+    leap_years += ( tm_year / 4 );
+    leap_years -= ( tm_year / 100 );
+    leap_years += ( ( tm_year + 300 ) / 400 );
+
+    return leap_years;
+}
+
+static int day_of_week ( int tm_year, int tm_mon, int tm_mday ) {
+    static const uint8_t offset[12] =
+        { 1, 4, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };
+    int pseudo_year = tm_year;
+
+    if ( tm_mon < 2 )
+        pseudo_year--;
+    return ( ( pseudo_year + leap_years_to_end ( pseudo_year ) +
+        offset[tm_mon] + tm_mday ) % 7 );
+}
+
+static void
+normalize(
+	int * tensptr,
+	int * unitsptr,
+	int	base
+	)
+{
+	if (*unitsptr >= base) {
+		*tensptr += *unitsptr / base;
+		*unitsptr %= base;
+	} else if (*unitsptr < 0) {
+		--*tensptr;
+		*unitsptr += base;
+		if (*unitsptr < 0) {
+			*tensptr -= 1 + (-*unitsptr) / base;
+			*unitsptr = base - (-*unitsptr) % base;
+		}
+	}
+}
+
+static struct tm *
+mkdst(
+	struct tm *	tmp
+	)
+{
+    /* jds */
+    static struct tm tmbuf;
+
+    tmbuf = *tmp;
+    tmbuf.tm_isdst = 1;
+    tmbuf.tm_min += DSTMINUTES;
+    normalize(&tmbuf.tm_hour, &tmbuf.tm_min, MINSPERHOUR);
+    return &tmbuf;
+}
+
+static int
+tmcomp(
+	register struct tm * atmp,
+	register struct tm * btmp
+	)
+{
+	register int	result;
+
+	/* compare down to the same day */
+
+	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+	    (result = (atmp->tm_mon - btmp->tm_mon)) == 0)
+	    result = (atmp->tm_mday - btmp->tm_mday);
+
+	if(result != 0)
+	    return result;
+
+	/* get rid of one-sided dst bias */
+
+	if(atmp->tm_isdst == 1 && !btmp->tm_isdst)
+	    btmp = mkdst(btmp);
+	else if(btmp->tm_isdst == 1 && !atmp->tm_isdst)
+	    atmp = mkdst(atmp);
+
+	/* compare the rest of the way */
+
+	if ((result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+	    (result = (atmp->tm_min - btmp->tm_min)) == 0)
+	    result = atmp->tm_sec - btmp->tm_sec;
+	return result;
+}
+
+
+static time_t
+time2(
+	struct tm *	tmp,
+	int * 		okayp
+	)
+{
+	register int			dir;
+	register int			bits;
+	register int			i;
+	register int			saved_seconds;
+	time_t				t;
+	struct tm			yourtm, mytm;
+
+	*okayp = FALSE;
+	yourtm = *tmp;
+	if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
+		normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
+	normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
+	normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
+	normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
+	while (yourtm.tm_mday <= 0) {
+		--yourtm.tm_year;
+		yourtm.tm_mday +=
+			year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
+	}
+	for ( ; ; ) {
+		i = mon_lengths[isleap(yourtm.tm_year +
+			TM_YEAR_BASE)][yourtm.tm_mon];
+		if (yourtm.tm_mday <= i)
+			break;
+		yourtm.tm_mday -= i;
+		if (++yourtm.tm_mon >= MONSPERYEAR) {
+			yourtm.tm_mon = 0;
+			++yourtm.tm_year;
+		}
+	}
+	saved_seconds = yourtm.tm_sec;
+	yourtm.tm_sec = 0;
+	/*
+	** Calculate the number of magnitude bits in a time_t
+	** (this works regardless of whether time_t is
+	** signed or unsigned, though lint complains if unsigned).
+	*/
+	for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+		;
+	/*
+	** If time_t is signed, then 0 is the median value,
+	** if time_t is unsigned, then 1 << bits is median.
+	*/
+	t = (t < 0) ? 0 : ((time_t) 1 << bits);
+	for ( ; ; ) {
+	        mytm = *localtime(&t);
+		dir = tmcomp(&mytm, &yourtm);
+		if (dir != 0) {
+			if (bits-- < 0)
+				return WRONG;
+			if (bits < 0)
+				--t;
+			else if (dir > 0)
+				t -= (time_t) 1 << bits;
+			else	t += (time_t) 1 << bits;
+			continue;
+		}
+		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+			break;
+
+		return WRONG;
+	}
+	t += saved_seconds;
+	*tmp = *localtime(&t);
+	*okayp = TRUE;
+	return t;
+}
+
+static time_t
+time1(
+	struct tm * tmp
+	)
+{
+	register time_t			t;
+	int				okay;
+
+	if (tmp->tm_isdst > 1)
+		tmp->tm_isdst = 1;
+	t = time2(tmp, &okay);
+
+    /*
+    ** Python actually uses tm_wday as a sentinel for mktime returning -1
+    ** so this weekday calculation is copied from a time.c implementation
+    ** the day-of-week number is not used in any time offset calculations,
+    ** but it's nice to have and it saves a unittest skip...
+    */
+    tmp->tm_wday = day_of_week(tmp->tm_year, tmp->tm_mon, tmp->tm_mday);
+
+	if (okay || tmp->tm_isdst < 0)
+		return t;
+
+	return WRONG;
+}
+
+time_t
+my_mktime(
+	struct tm * tmp
+	)
+{
+	return time1(tmp);
+}
--- /dev/null	Fri Sep 20 17:28:33 2019
+++ Modules/setenv.c	Sat Sep 14 22:28:30 2019
@@ -0,0 +1,110 @@
+/*************************************************************************\
+*                  Copyright (C) Michael Kerrisk, 2019.                   *
+*                                                                         *
+* This program is free software. You may use, modify, and redistribute it *
+* under the terms of the GNU General Public License as published by the   *
+* Free Software Foundation, either version 3 or (at your option) any      *
+* later version. This program is distributed without any warranty.  See   *
+* the file COPYING.gpl-v3 for details.                                    *
+\*************************************************************************/
+
+/* setenv.c
+
+   An implementation of setenv() and unsetenv() using environ, putenv(),
+   and getenv().
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+int
+unsetenv(const char *name)
+{
+    extern char **environ;
+    char **ep, **sp;
+    size_t len;
+
+    if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    len = strlen(name);
+
+    for (ep = environ; *ep != NULL; )
+        if (strncmp(*ep, name, len) == 0 && (*ep)[len] == '=') {
+
+            /* Remove found entry by shifting all successive entries
+               back one element */
+
+            for (sp = ep; *sp != NULL; sp++)
+                *sp = *(sp + 1);
+
+            /* Continue around the loop to further instances of 'name' */
+
+        } else {
+            ep++;
+        }
+
+    return 0;
+}
+
+int
+setenv(const char *name, const char *value, int overwrite)
+{
+    char *es;
+
+    if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
+            value == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (getenv(name) != NULL && overwrite == 0)
+        return 0;
+
+    unsetenv(name);             /* Remove all occurrences */
+
+    es = malloc(strlen(name) + strlen(value) + 2);
+                                /* +2 for '=' and null terminator */
+    if (es == NULL)
+        return -1;
+
+    strcpy(es, name);
+    strcat(es, "=");
+    strcat(es, value);
+
+    return (putenv(es) != 0) ? -1 : 0;
+}
+
+#ifdef TEST_IT
+
+int
+main()
+{
+    if (putenv("TT=xxxxx") != 0)
+        perror("putenv");
+
+    system("echo '***** Environment before unsetenv(TT)'; "
+            "printenv | grep ^TT");
+    system("echo 'Total lines from printenv:' `printenv | wc -l`");
+
+    unsetenv("TT");
+
+    system("echo '***** Environment after unsetenv(TT)'; "
+            "printenv | grep ^TT");
+    system("echo 'Total lines from printenv:' `printenv | wc -l`");
+
+    setenv("xyz", "one", 1);
+    setenv("xyz", "two", 0);
+    setenv("xyz2", "222", 0);
+
+    system("echo '***** Environment after setenv() calls'; "
+            "printenv | grep ^x");
+    system("echo 'Total lines from printenv:' `printenv | wc -l`");
+
+    exit(EXIT_SUCCESS);
+}
+
+#endif
