diff -uP stunnel-3.8p4/Makefile.w32 stunnel/Makefile.w32
--- stunnel-3.8p4/Makefile.w32	Sun Jun 25 17:55:54 2000
+++ stunnel/Makefile.w32	Sun Aug 20 21:45:06 2000
@@ -1,6 +1,9 @@
+# -*- Makefile -*-
+# 
 # Simple Makefile.w32 for stunnel.exe by Michal Trojnara 1998-2000
 #
 # Modified by Brian Hatch  (bri@stunnel.org)
+# Modified by Robert Spier (rspier@pobox.com) for Win32UI
 
 # This makefile is only tested on the mingw compiler.  Mingw
 # can successfully compile both openssl and stunnel.  If you want
@@ -10,10 +13,8 @@
 # (You did already compile openssl, didn't you???)
 SSLDIR=../openssl-0.9.5a
 
+DEFINES=-DUSE_WIN32 -DHAVE_OPENSSL 
 
-
-DEFINES=-DUSE_WIN32 -DHAVE_OPENSSL
-
 # You may want to add some of the following flags
 # to the DEFINES definition above.
 
@@ -38,10 +39,35 @@
 LIBS=-L$(SSLDIR)/out -leay32 -lssl32 -lwsock32 -lgdi32
 OBJS=stunnel.o ssl.o protocol.o sthreads.o log.o
 
+EXE=stunnel.exe
+
+all:
+	@echo use either:
+	@echo   make stunnel.exe  - command line stunnel
+	@echo   make stunnelw.exe - gui stunnel
+	@echo .
+	@echo Be sure to do a "make clean" between stunnel and
+	@echo  stunnelw compilations.
+
 stunnel.exe: $(OBJS)
-	$(CC) $(LDFLAGS) -o stunnel.exe $(OBJS) $(LIBS)
+	$(CC) $(LDFLAGS) -o $(EXE) $(OBJS) $(LIBS)
 
+
 clean:
 	del *.o
 	del stunnel.exe
+	del stunnelw.exe
+
+# for the Win32 UI
+W_OBJS = resource.o stunnelw.o
+stunnelw.exe: OBJS += $(W_OBJS)
+stunnelw.exe: LDFLAGS += -mwindows
+stunnelw.exe: CFLAGS += -DUSE_WIN32UI
+stunnelw.exe: EXE := stunnelw.exe
+stunnelw.exe: $(W_OBJS) $(OBJS)
+	$(CC) $(LDFLAGS) -o $(EXE) $(OBJS) $(LIBS)
+
 
+stunnelw.rc:
+resource.o: stunnelw.rc resource.h
+	    windres stunnelw.rc resource.o
Binary files stunnel-3.8p4/backup1.zip and stunnel/backup1.zip differ
diff -uP stunnel-3.8p4/common.h stunnel/common.h
--- stunnel-3.8p4/common.h	Sun Jun 25 17:58:24 2000
+++ stunnel/common.h	Sun Aug 20 20:42:14 2000
@@ -219,6 +219,19 @@
 #define STRINGIFY_H(x) #x
 #define STRINGIFY(x) STRINGIFY_H(x)
 
+#ifdef USE_WIN32UI
+
+static char status_string[80];
+
+#define exit win32_exit
+#define main stunnel_main
+
+
+void win32_exit(int);
+void update_trayicon(char *);
+void win32_log(char*);
+void win32_log_unixlines(char*);
+#endif
 
 /* End of common.h */
 
Common subdirectories: stunnel-3.8p4/doc.polish and stunnel/doc.polish
Binary files stunnel-3.8p4/icon.ico and stunnel/icon.ico differ
Binary files stunnel-3.8p4/icon1.ico and stunnel/icon1.ico differ
Binary files stunnel-3.8p4/icon2.ico and stunnel/icon2.ico differ
diff -uP stunnel-3.8p4/log.c stunnel/log.c
--- stunnel-3.8p4/log.c	Mon Feb 14 11:16:02 2000
+++ stunnel/log.c	Sat Aug 19 22:29:08 2000
@@ -71,8 +71,13 @@
         syslog(level, text);
     else
 #endif
+
+#ifdef USE_WIN32UI
+      win32_log(text);
+#else
         fprintf(stderr, "LOG%d[%lu:%lu]: %s\n",
             level, process_id(), thread_id(), text);
     fflush(stderr);
+#endif
 }
 
Binary files stunnel-3.8p4/log.o and stunnel/log.o differ
Binary files stunnel-3.8p4/protocol.o and stunnel/protocol.o differ
diff -uP stunnel-3.8p4/resource.h stunnel/resource.h
--- stunnel-3.8p4/resource.h	Wed Dec 31 19:00:00 1969
+++ stunnel/resource.h	Sun Aug 20 22:15:28 2000
@@ -0,0 +1,9 @@
+#define IDR_STUNNEL_MENU                101
+#define IDR_TRAYMENU                    102
+#define IDI_STUNNEL                     105
+#define IDD_DIALOG1                     106
+#define ID_FILE_SAVE                    40001
+#define ID_FILE_EXIT                    40002
+#define ID_HELP_ABOUT                   40003
+#define ID_SHOW_LOGWINDOW               40004
+
Binary files stunnel-3.8p4/resource.o and stunnel/resource.o differ
Binary files stunnel-3.8p4/ssl.o and stunnel/ssl.o differ
Binary files stunnel-3.8p4/sthreads.o and stunnel/sthreads.o differ
diff -uP stunnel-3.8p4/stunnel.c stunnel/stunnel.c
--- stunnel-3.8p4/stunnel.c	Sun Jun 25 17:58:34 2000
+++ stunnel/stunnel.c	Sun Aug 20 14:44:12 2000
@@ -59,7 +59,6 @@
 #define Win32_Winsock
 #include <windows.h>
 
-
 static struct WSAData wsa_state;
 
 #else /* defined USE_WIN32 */
@@ -171,6 +170,20 @@
     }
     log(LOG_NOTICE, "Using '%s' as tcpwrapper service name", options.servname);
 
+#ifdef USE_WIN32UI
+    {
+#ifdef HAVE_SNPRINTF		
+      snprintf(status_string,80,
+#else
+      sprintf(status_string,
+#endif
+	       "stunnel: %d -> %s",
+		ntohs(options.localport),
+		options.servname );
+      update_trayicon( status_string );
+    }
+#endif 
+
     /* check if certificate exists */
     if(options.option&OPT_CERT) {
         if(stat(options.pem, &st)) {
@@ -1011,7 +1024,11 @@
 
 static void print_help()
 {
+#ifdef USE_WIN32UI
+  win32_log_unixlines(
+#else
     fprintf(stderr,
+#endif
 /* Server execution */
 	"\nstunnel\t"
 	"[-h] "
Only in stunnel-3.8p4: stunnel.exe
Binary files stunnel-3.8p4/stunnel.o and stunnel/stunnel.o differ
diff -uP stunnel-3.8p4/stunnelw.c stunnel/stunnelw.c
--- stunnel-3.8p4/stunnelw.c	Wed Dec 31 19:00:00 1969
+++ stunnel/stunnelw.c	Sun Aug 20 22:17:44 2000
@@ -0,0 +1,323 @@
+/*
+ * stunnelw - Win32 User Interface for Stunnel
+ *
+ * Copyright (c) 2000 Robert Spier <rspier@pobox.com>
+ *               All Rights Reserved
+ *
+ * see stunnel.c for more information about stunnel 
+ *
+ * Special Thanks for this file:
+ *   Ron Isaacson
+ *   Charles Petzold
+ *   And, Microsoft who gave me Petzold's book for free.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
+ */
+
+#ifdef USE_WIN32UI
+#include <windows.h>
+#include <stdio.h>
+#include <malloc.h>
+#include "common.h"
+#include "resource.h"
+
+HICON hicon_stunnel;
+HWND g_hwnd;
+HWND g_hwndEdit;
+HINSTANCE g_hinstance;
+int stunnel_main(int argc, char* argv[]);
+
+#define IDM_LOG 1
+
+/* windows provides us with a single string for the command line.
+   stunnel_main wants it split into argc/argv */
+void start_stunnel_main( LPSTR szCmdLine ) {
+  char *argvp[128];
+  int i=1;
+  
+  char *p = strtok(szCmdLine," ");
+  while( p ) {
+    argvp[i++] = p;
+    p = strtok(NULL," ");
+  }
+  argvp[0]="stunnel";
+
+  stunnel_main(i,argvp);
+}
+
+/* Win32 Message Handling Procedure */
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, 
+			  LPARAM lParam) {
+  static int toggleShow = 0;
+  static HWND hwndStunnelInfo;
+  static OPENFILENAME ofn;
+  static char logFileName[256];
+
+  switch(message) {
+  case WM_CREATE:
+    g_hwnd = hwnd;
+    {
+      DWORD threadID;
+      
+      g_hwndEdit = CreateWindow( TEXT("edit"), NULL,
+				 WS_CHILD | WS_VISIBLE | WS_HSCROLL | 
+				 WS_VSCROLL | WS_BORDER | ES_LEFT | 
+				 ES_MULTILINE | ES_READONLY | 
+				 ES_AUTOHSCROLL | ES_AUTOVSCROLL,
+				 0,0,0,0, hwnd, (HMENU) IDM_LOG,
+				 ((LPCREATESTRUCT)lParam)->hInstance, NULL );
+
+	hwndStunnelInfo = CreateWindow( TEXT("static"), TEXT( STUNNEL_INFO ),
+				   WS_CHILD| WS_VISIBLE | SS_SUNKEN | SS_RIGHT,
+				   0,0,0,0, hwnd, NULL,
+				   ((LPCREATESTRUCT)lParam)->hInstance, NULL );
+				   
+	update_trayicon( status_string );
+	CloseHandle(CreateThread(NULL, 0, 
+				 (LPTHREAD_START_ROUTINE)start_stunnel_main,
+				 (void *)(((LPCREATESTRUCT)lParam)->lpCreateParams), 
+				 0, &threadID));
+
+	logFileName[0] = 0;
+	ofn.lStructSize = sizeof( OPENFILENAME);
+	ofn.hwndOwner = hwnd;
+	ofn.hInstance=NULL;
+	ofn.lpstrFilter = NULL;
+	ofn.lpstrCustomFilter = NULL;
+	ofn.nMaxCustFilter = 0;
+	ofn.nFilterIndex = 0;
+	ofn.lpstrFile = logFileName;
+	ofn.nMaxFile = 256;
+	ofn.lpstrFileTitle = NULL;
+	ofn.nMaxFileTitle = 0;
+	ofn.lpstrInitialDir = NULL;
+	ofn.lpstrTitle= NULL;
+	ofn.Flags = OFN_OVERWRITEPROMPT;
+	ofn.nFileOffset=0;
+	ofn.nFileExtension=0;
+	ofn.lpstrDefExt = TEXT("log");
+	ofn.lCustData = 0;
+	ofn.lpfnHook = NULL;
+	ofn.lpTemplateName = NULL;
+    }
+    return 0;
+
+  case WM_SETFOCUS:
+    SetFocus(g_hwndEdit);
+    
+  case WM_USER:			/* coming from the tray icon */
+    if ( lParam == WM_LBUTTONDBLCLK ) {
+      toggleShow = !toggleShow;
+      if (toggleShow) {
+	ShowWindow(hwnd, SW_SHOW);
+	SetForegroundWindow( hwnd );
+      }
+      else
+	ShowWindow(hwnd, SW_HIDE);
+    }
+
+
+    if ( lParam == WM_RBUTTONUP ) {
+      POINT pt;
+      HMENU hMenu = LoadMenu( g_hinstance, MAKEINTRESOURCE(IDR_TRAYMENU));
+      GetCursorPos(&pt);
+      //      SetForegroundWindow( hwnd );
+      TrackPopupMenu( GetSubMenu(hMenu,0), TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON,
+		      pt.x, pt.y, 0, hwnd, NULL);
+      DestroyMenu(hMenu);
+    }
+    return 0;
+  case WM_SIZE:
+    /* we didn't set the size of the window on creation, so set it now */
+    MoveWindow( g_hwndEdit, 0,0, LOWORD(lParam), HIWORD(lParam)-0, TRUE);
+    return 0;
+
+    case WM_COMMAND:
+      switch (LOWORD (wParam)) {
+      case IDM_LOG:
+      /* Possible errors from Log Editbox */
+	if (HIWORD(wParam) == EN_ERRSPACE ||
+	    HIWORD(wParam) == EN_MAXTEXT)
+	  MessageBox(g_hwnd, TEXT("Edit control out of space."),
+		     "stunnel", MB_OK | MB_ICONSTOP);
+	return 0;
+
+      case ID_SHOW_LOGWINDOW:
+	SendMessage(hwnd,WM_USER,0,WM_LBUTTONDBLCLK);
+	return 0;
+
+      case ID_FILE_EXIT:
+	SendMessage(hwnd,WM_DESTROY,0,0);
+	return 0;
+
+      case ID_HELP_ABOUT:
+	MessageBox(g_hwnd, 
+		   STUNNEL_INFO,
+		   "About stunnel...",
+		   MB_OK | MB_ICONINFORMATION );
+	return 0;
+
+      case ID_FILE_SAVE:
+	if (!GetSaveFileName(&ofn))
+	  return 0;
+
+	{
+	  FILE *f;
+	  SetCursor(LoadCursor(NULL,IDC_WAIT));
+	  ShowCursor(TRUE);
+
+	  f = fopen(logFileName,"w+");
+	  if (f) {
+	    int slength = SendMessage( g_hwndEdit, WM_GETTEXTLENGTH, 0,0 ) + 1;
+	    char *string = malloc(slength + 2);
+
+	    SendMessage( g_hwndEdit, WM_GETTEXT, slength, (int)string );	    
+	    fprintf(f,"%s",string);
+	    fclose(f);
+	  } else {
+	    MessageBox( hwnd, TEXT("Cannot save logfile..."),
+			"Error", MB_ICONERROR | MB_OK );
+	  }
+	    ShowCursor(FALSE);
+	    SetCursor(LoadCursor(NULL,IDC_ARROW));
+	}
+
+      } // switch
+      break;
+
+  case WM_DESTROY: 
+    {
+      NOTIFYICONDATA nid;
+      HICON icon = LoadIcon( g_hinstance, MAKEINTRESOURCE( IDI_STUNNEL )); 
+      nid.cbSize = sizeof (NOTIFYICONDATA);
+      nid.hWnd = g_hwnd;
+      nid.uID = 0;
+      nid.hIcon = icon;
+      nid.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON;
+      nid.uCallbackMessage = WM_USER;
+      Shell_NotifyIcon( NIM_DELETE, &nid );
+      PostQuitMessage (0);
+      return 0;
+    }
+  } 
+
+  return DefWindowProc( hwnd, message, wParam, lParam );
+}
+
+/* Win32 main(), initialization and such */
+int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
+		     LPSTR szCmdLine, int iCmdShow) {
+  
+  static TCHAR szAppName[] = TEXT ("stunnel");
+  HWND hwnd;
+  MSG msg;
+  WNDCLASS wndclass;
+
+  wndclass.style = CS_HREDRAW | CS_VREDRAW;
+  wndclass.lpfnWndProc = WndProc;
+  wndclass.cbClsExtra = 0;
+  wndclass.cbWndExtra = 0;
+  wndclass.hInstance = hInstance;
+  wndclass.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_STUNNEL));
+  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+  wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+  wndclass.lpszMenuName = TEXT("IDR_STUNNELMENU");
+  wndclass.lpszClassName = szAppName;
+
+  RegisterClass(&wndclass);
+
+  g_hinstance = hInstance;
+
+  strncpy(status_string,"stunnel: initalizing",80);
+
+  hwnd = CreateWindow( szAppName, TEXT( STUNNEL_INFO ), 
+		       WS_OVERLAPPEDWINDOW, 
+		       CW_USEDEFAULT, CW_USEDEFAULT, 
+		       CW_USEDEFAULT, CW_USEDEFAULT, 
+		       NULL, NULL, hInstance, szCmdLine);
+  
+  ShowWindow( hwnd, SW_HIDE);
+  UpdateWindow(hwnd);
+
+  /* Win32 Message Loop */
+  while( GetMessage(&msg, NULL, 0,0) ) {
+    TranslateMessage(&msg);
+    DispatchMessage(&msg);
+  }
+  return msg.wParam;
+}
+
+/* update the tooltip on the tray icon */   
+void update_trayicon(LPSTR szIconStr) {
+  static DWORD nim = NIM_ADD;
+  HICON icon = LoadIcon(g_hinstance, MAKEINTRESOURCE(IDI_STUNNEL)); 
+  NOTIFYICONDATA nid;
+
+
+  nid.cbSize = sizeof (NOTIFYICONDATA);
+  nid.hWnd = g_hwnd;
+  nid.uID = 0;
+  nid.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON;
+  nid.uCallbackMessage = WM_USER;
+  nid.hIcon = icon;
+  lstrcpy (nid.szTip, szIconStr);
+  Shell_NotifyIcon (nim, &nid);
+  nim = NIM_MODIFY;
+  DestroyIcon( icon );
+}      
+
+/* append a message to the log buffer */
+void win32_log(char *text) {
+    int slength = SendMessage( g_hwndEdit, WM_GETTEXTLENGTH, 0,0 ) + 1;
+    char *string = malloc(slength + strlen(text) + 4);
+    int offset = 0;
+    if (slength > 20000)	/* if we're getting long, cut first 5k out */
+      offset = 5000;
+    SendMessage( g_hwndEdit, WM_GETTEXT, slength, (int)string );
+    strcat( string, text );
+    strcat( string, "\r\n" );
+    SendMessage( g_hwndEdit, WM_SETTEXT, strlen(string)-offset, 
+		 (int)string+offset);
+    free(string);
+}
+
+/* exit the current thread and bring the log window to the front */
+void win32_exit(int v) {
+  fprintf(stderr,"exit %d",v);
+  win32_log("");
+  win32_log("stunnel has terminated.\r\n"
+	    "close this log window to terminate the process");
+  ShowWindow( g_hwnd, SW_SHOW);
+  SetForegroundWindow( g_hwnd );
+  ExitThread(v);
+}
+
+/* append multiple \n seperated lines to the log buffer */
+void win32_log_unixlines(char *text) {
+  char *textcopy;
+  char *line;
+  textcopy = malloc(strlen(text));
+  strcpy(textcopy,text);
+  /* this is really inneficient, mostly because of win32_log.
+     But.. Its the easiest way to this. */
+  line = strtok(textcopy,"\n");
+  while ( line ) {
+    win32_log(line);
+    line = strtok(NULL,"\n");
+  }
+  free(textcopy);
+}
+
+#endif
Binary files stunnel-3.8p4/stunnelw.exe and stunnel/stunnelw.exe differ
Binary files stunnel-3.8p4/stunnelw.o and stunnel/stunnelw.o differ
diff -uP stunnel-3.8p4/stunnelw.rc stunnel/stunnelw.rc
--- stunnel-3.8p4/stunnelw.rc	Wed Dec 31 19:00:00 1969
+++ stunnel/stunnelw.rc	Sun Aug 20 22:16:52 2000
@@ -0,0 +1,58 @@
+#include "resource.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_STUNNELMENU MENU DISCARDABLE 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&Save",                       ID_FILE_SAVE
+        MENUITEM "E&xit",                       ID_FILE_EXIT
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About",                      ID_HELP_ABOUT
+    END
+END
+
+IDR_TRAYMENU MENU DISCARDABLE
+BEGIN 
+  POPUP "&File"
+  BEGIN
+  MENUITEM "&About", ID_HELP_ABOUT
+  MENUITEM "Show &Log", ID_SHOW_LOGWINDOW
+  MENUITEM "E&xit", ID_FILE_EXIT
+  END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_STUNNEL             ICON    DISCARDABLE     "icon2.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+/*
+IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 187, 95
+STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,130,7,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,130,24,50,14
+END
+
+
+*/
