Martin Prikryl 21 years ago
parent
commit
8e807e500e
100 changed files with 6873 additions and 2949 deletions
  1. 4 4
      DragExt.bpr
  2. BIN
      DragExt.res
  3. 1 1
      Putty.bpr
  4. 2 2
      ScpForms.bpf
  5. 15 15
      ScpForms.bpr
  6. 13 10
      WinSCP3.bpr
  7. 2 2
      WinSCP3.drc
  8. BIN
      WinSCP3.res
  9. 6 0
      components/UnixDriveView.cpp
  10. 0 13
      core/Common.cpp
  11. 0 1
      core/Common.h
  12. 3 3
      core/Configuration.cpp
  13. 2 2
      core/Net.cpp
  14. 3 2
      core/PuttyIntf.c
  15. 1 0
      core/PuttyIntf.h
  16. 17 76
      core/Queue.cpp
  17. 2 0
      core/Queue.h
  18. 23 1
      core/RemoteFiles.cpp
  19. 3 1
      core/RemoteFiles.h
  20. 1 1
      core/ScpFileSystem.cpp
  21. 34 6
      core/SecureShell.cpp
  22. 3 1
      core/SecureShell.h
  23. 12 1
      core/SessionData.cpp
  24. 3 0
      core/SessionData.h
  25. 122 10
      core/SftpFileSystem.cpp
  26. 168 4
      core/Terminal.cpp
  27. 23 0
      core/Terminal.h
  28. 221 181
      forms/CustomScpExplorer.cpp
  29. 9 6
      forms/CustomScpExplorer.h
  30. 47 11
      forms/Editor.cpp
  31. 2 1
      forms/Editor.dfm
  32. 7 1
      forms/Editor.h
  33. 2 0
      forms/FileSystemInfo.cpp
  34. 8 8
      forms/Login.dfm
  35. 14 0
      forms/MessageDlg.cpp
  36. 3 5
      forms/NonVisual.cpp
  37. 6 0
      forms/NonVisual.dfm
  38. 0 41
      forms/NonVisual.dti
  39. 2 0
      forms/NonVisual.h
  40. 7 0
      forms/Preferences.cpp
  41. 131 61
      forms/Preferences.dfm
  42. 9 3
      forms/Preferences.h
  43. 2 4
      forms/ScpCommander.cpp
  44. 2 2
      forms/Synchronize.cpp
  45. 1 1
      forms/Synchronize.dfm
  46. 1 1
      makefile
  47. 108 0
      packages/DiscMon_B5.bpk
  48. 13 0
      packages/DiscMon_B5.cpp
  49. BIN
      packages/DiscMon_B5.res
  50. 12 7
      packages/my/DiscMon.hpp
  51. 45 24
      packages/my/DiscMon.pas
  52. 15 3
      putty/CMDGEN.C
  53. 7 0
      putty/CMDLINE.C
  54. 15 8
      putty/CONFIG.C
  55. 1 1
      putty/CONSOLE.C
  56. 25 6
      putty/LDISC.C
  57. 341 321
      putty/MAKEFILE.BOR
  58. 372 351
      putty/MAKEFILE.CYG
  59. 340 318
      putty/MAKEFILE.LCC
  60. 354 347
      putty/MAKEFILE.VC
  61. 1788 0
      putty/MINIBIDI.C
  62. 456 0
      putty/MINIBIDI.H
  63. 4 0
      putty/MISC.C
  64. 788 742
      putty/MKFILES.PL
  65. 1 0
      putty/MKUNXARC.SH
  66. 5 5
      putty/NETWORK.H
  67. 0 26
      putty/NOISE.C
  68. 189 31
      putty/PAGEANT.C
  69. 15 3
      putty/PLINK.C
  70. 1 1
      putty/PORTFWD.C
  71. 2 2
      putty/PPROXY.C
  72. 6 5
      putty/PROXY.C
  73. 56 11
      putty/PSFTP.C
  74. 2 2
      putty/PUTTYGEN.C
  75. 3 2
      putty/RAW.C
  76. 11 1
      putty/README
  77. 84 4
      putty/RECIPE
  78. 2 2
      putty/RLOGIN.C
  79. 94 18
      putty/SCP.C
  80. 10 2
      putty/SETTINGS.C
  81. 291 131
      putty/SSH.C
  82. 11 6
      putty/SSH.H
  83. 25 7
      putty/SSHBN.C
  84. 1 1
      putty/SSHDH.C
  85. 14 14
      putty/SSHPUBK.C
  86. 49 15
      putty/SSHRSA.C
  87. 2 2
      putty/TELNET.C
  88. 152 6
      putty/TERMINAL.C
  89. 8 0
      putty/TERMINAL.H
  90. 5 5
      putty/TESTBACK.C
  91. 11 0
      putty/WILDCARD.C
  92. 85 5
      putty/WINDOW.C
  93. 4 2
      putty/WINHELP.H
  94. 3 2
      putty/WINMISC.C
  95. 38 1
      putty/WINNET.C
  96. 1 1
      putty/WINUTILS.C
  97. 33 18
      putty/X11FWD.C
  98. 25 1
      putty/putty.org.h
  99. 3 0
      resource/TextsCore.h
  100. 10 7
      resource/TextsCore1.rc

+ 4 - 4
DragExt.bpr

@@ -61,8 +61,8 @@ IncludeVerInfo=1
 AutoIncBuild=1
 MajorVer=1
 MinorVer=1
-Release=2
-Build=39
+Release=3
+Build=41
 Debug=0
 PreRelease=0
 Special=0
@@ -74,13 +74,13 @@ CodePage=1252
 [Version Info Keys]
 CompanyName=Martin Prikryl
 FileDescription=Drag&Drop shell extension for WinSCP
-FileVersion=1.1.2.39
+FileVersion=1.1.3.41
 InternalName=dragext
 LegalCopyright=(c) 2004 Martin Prikryl
 LegalTrademarks=
 OriginalFilename=dragext.dll
 ProductName=WinSCP
-ProductVersion=3.6.6.0
+ProductVersion=3.6.7.0
 Comments=
 WWW=http://winscp.sourceforge.net/
 

BIN
DragExt.res


+ 1 - 1
Putty.bpr

@@ -27,7 +27,7 @@
     <PATHRC value=".;"/>
     <PATHASM value=".;"/>
     <LINKER value="TLib"/>
-    <USERDEFINES value="PUTTY_LIB;GSSAPI;_WINDOWS;_MSC_VER=1000"/>
+    <USERDEFINES value="PUTTY_LIB;GSSAPI;MPEXT;_WINDOWS;_MSC_VER=1000"/>
     <SYSDEFINES value="_RTLDLL;NO_STRICT"/>
     <MAINSOURCE value="Putty.bpf"/>
     <INCLUDEPATH value="putty;putty\CHARSET;$(BCB)\include;$(BCB)\include\vcl"/>

+ 2 - 2
ScpForms.bpf

@@ -4,10 +4,10 @@
 #pragma hdrstop
 USEFORM("forms\About.cpp", AboutDialog);
 USEFORM("forms\Cleanup.cpp", CleanupDialog);
+USEFORM("forms\ComboInput.cpp", ComboInputDialog);
 USEFORM("forms\Console.cpp", ConsoleDialog);
 USEFORM("forms\Copy.cpp", CopyDialog);
 USEFORM("forms\CopyParams.cpp", CopyParamsFrame); /* TFrame: File Type */
-USEFORM("forms\ComboInput.cpp", ComboInputDialog);
 USEFORM("forms\Editor.cpp", EditorForm);
 USEFORM("forms\FileSystemInfo.cpp", FileSystemInfoDialog);
 USEFORM("forms\FullSynchronize.cpp", FullSynchronizeDialog);
@@ -16,8 +16,8 @@ USEFORM("forms\ImportSessions.cpp", ImportSessionsDialog);
 USEFORM("forms\Licence.cpp", LicenceDialog);
 USEFORM("forms\LocationProfiles.cpp", LocationProfilesDialog);
 USEFORM("forms\Log.cpp", LogForm);
-USEFORM("forms\LogSettings.cpp", LoggingFrame); /* TFrame: File Type */
 USEFORM("forms\Login.cpp", LoginDialog);
+USEFORM("forms\LogSettings.cpp", LoggingFrame); /* TFrame: File Type */
 USEFORM("forms\OpenDirectory.cpp", OpenDirectoryDialog);
 USEFORM("forms\OperationStatus.cpp", OperationStatusForm);
 USEFORM("forms\Password.cpp", PasswordDialog);

+ 15 - 15
ScpForms.bpr

@@ -5,24 +5,24 @@
     <VERSION value="BCB.06.00"/>
     <PROJECT value="lib\ScpForms.lib"/>
     <OBJFILES value="forms\InputDlg.obj forms\MessageDlg.obj windows\VCLCommon.obj 
-      forms\About.obj forms\Cleanup.obj forms\Console.obj forms\Copy.obj 
-      forms\CopyParams.obj forms\ComboInput.obj forms\Editor.obj 
-      forms\FileSystemInfo.obj forms\FullSynchronize.obj 
+      forms\About.obj forms\Cleanup.obj forms\ComboInput.obj 
+      forms\Console.obj forms\Copy.obj forms\CopyParams.obj 
+      forms\Editor.obj forms\FileSystemInfo.obj forms\FullSynchronize.obj 
       forms\GeneralSettings.obj forms\ImportSessions.obj forms\Licence.obj 
-      forms\LocationProfiles.obj forms\Log.obj forms\LogSettings.obj 
-      forms\Login.obj forms\OpenDirectory.obj forms\OperationStatus.obj 
-      forms\Password.obj forms\Preferences.obj forms\Progress.obj 
-      forms\Properties.obj forms\Rights.obj forms\RightsExt.obj 
-      forms\SelectMask.obj forms\Symlink.obj forms\Synchronize.obj 
-      forms\SynchronizeProgress.obj"/>
+      forms\LocationProfiles.obj forms\Log.obj forms\Login.obj 
+      forms\LogSettings.obj forms\OpenDirectory.obj 
+      forms\OperationStatus.obj forms\Password.obj forms\Preferences.obj 
+      forms\Progress.obj forms\Properties.obj forms\Rights.obj 
+      forms\RightsExt.obj forms\SelectMask.obj forms\Symlink.obj 
+      forms\Synchronize.obj forms\SynchronizeProgress.obj"/>
     <RESFILES value=""/>
     <DEFFILE value=""/>
-    <RESDEPEN value="$(RESFILES) forms\About.dfm forms\Cleanup.dfm forms\Console.dfm 
-      forms\Copy.dfm forms\CopyParams.dfm forms\ComboInput.dfm forms\Editor.dfm 
+    <RESDEPEN value="$(RESFILES) forms\About.dfm forms\Cleanup.dfm forms\ComboInput.dfm 
+      forms\Console.dfm forms\Copy.dfm forms\CopyParams.dfm forms\Editor.dfm 
       forms\FileSystemInfo.dfm forms\FullSynchronize.dfm 
       forms\GeneralSettings.dfm forms\ImportSessions.dfm forms\Licence.dfm 
-      forms\LocationProfiles.dfm forms\Log.dfm forms\LogSettings.dfm 
-      forms\Login.dfm forms\OpenDirectory.dfm forms\OperationStatus.dfm 
+      forms\LocationProfiles.dfm forms\Log.dfm forms\Login.dfm 
+      forms\LogSettings.dfm forms\OpenDirectory.dfm forms\OperationStatus.dfm 
       forms\Password.dfm forms\Preferences.dfm forms\Progress.dfm 
       forms\Properties.dfm forms\Rights.dfm forms\RightsExt.dfm 
       forms\SelectMask.dfm forms\Symlink.dfm forms\Synchronize.dfm 
@@ -72,10 +72,10 @@
       <FILE FILENAME="windows\VCLCommon.cpp" FORMNAME="" UNITNAME="VCLCommon" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\About.cpp" FORMNAME="AboutDialog" UNITNAME="About" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Cleanup.cpp" FORMNAME="CleanupDialog" UNITNAME="Cleanup" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="forms\ComboInput.cpp" FORMNAME="ComboInputDialog" UNITNAME="ComboInput" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Console.cpp" FORMNAME="ConsoleDialog" UNITNAME="Console" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Copy.cpp" FORMNAME="CopyDialog" UNITNAME="Copy" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\CopyParams.cpp" FORMNAME="CopyParamsFrame" UNITNAME="CopyParams" CONTAINERID="CCompiler" DESIGNCLASS="TFrame" LOCALCOMMAND=""/>
-      <FILE FILENAME="forms\ComboInput.cpp" FORMNAME="ComboInputDialog" UNITNAME="ComboInput" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Editor.cpp" FORMNAME="EditorForm" UNITNAME="Editor" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\FileSystemInfo.cpp" FORMNAME="FileSystemInfoDialog" UNITNAME="FileSystemInfo" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\FullSynchronize.cpp" FORMNAME="FullSynchronizeDialog" UNITNAME="FullSynchronize" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
@@ -84,8 +84,8 @@
       <FILE FILENAME="forms\Licence.cpp" FORMNAME="LicenceDialog" UNITNAME="Licence" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\LocationProfiles.cpp" FORMNAME="LocationProfilesDialog" UNITNAME="LocationProfiles" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Log.cpp" FORMNAME="LogForm" UNITNAME="Log" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
-      <FILE FILENAME="forms\LogSettings.cpp" FORMNAME="LoggingFrame" UNITNAME="LogSettings" CONTAINERID="CCompiler" DESIGNCLASS="TFrame" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Login.cpp" FORMNAME="LoginDialog" UNITNAME="Login" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="forms\LogSettings.cpp" FORMNAME="LoggingFrame" UNITNAME="LogSettings" CONTAINERID="CCompiler" DESIGNCLASS="TFrame" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\OpenDirectory.cpp" FORMNAME="OpenDirectoryDialog" UNITNAME="OpenDirectory" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\OperationStatus.cpp" FORMNAME="OperationStatusForm" UNITNAME="OperationStatus" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\Password.cpp" FORMNAME="PasswordDialog" UNITNAME="Password" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>

+ 13 - 10
WinSCP3.bpr

@@ -5,11 +5,12 @@
     <VERSION value="BCB.06.00"/>
     <PROJECT value="WinSCP3.exe"/>
     <OBJFILES value="WinSCP3.obj forms\CustomScpExplorer.obj 
-      windows\CustomWinConfiguration.obj windows\GUIConfiguration.obj 
-      windows\GUITools.obj forms\NonVisual.obj windows\ProgParams.obj 
-      windows\QueueController.obj forms\ScpCommander.obj 
-      forms\ScpExplorer.obj windows\TerminalManager.obj windows\Tools.obj 
-      windows\UserInterface.obj windows\WinConfiguration.obj 
+      windows\CustomWinConfiguration.obj windows\EditorManager.obj 
+      windows\GUIConfiguration.obj windows\GUITools.obj forms\NonVisual.obj 
+      windows\ProgParams.obj windows\QueueController.obj 
+      forms\ScpCommander.obj forms\ScpExplorer.obj 
+      windows\SynchronizeController.obj windows\TerminalManager.obj 
+      windows\Tools.obj windows\UserInterface.obj windows\WinConfiguration.obj 
       windows\WinInterface.obj windows\WinMain.obj"/>
     <RESFILES value="windows\Windows.res WinSCP3.res"/>
     <DEFFILE value=""/>
@@ -70,6 +71,7 @@
       <FILE FILENAME="WinSCP3.cpp" FORMNAME="" UNITNAME="WinSCP3" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\CustomScpExplorer.cpp" FORMNAME="CustomScpExplorerForm" UNITNAME="CustomScpExplorer" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\CustomWinConfiguration.cpp" FORMNAME="" UNITNAME="CustomWinConfiguration" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="windows\EditorManager.cpp" FORMNAME="" UNITNAME="EditorManager" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\GUIConfiguration.cpp" FORMNAME="" UNITNAME="GUIConfiguration" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\GUITools.cpp" FORMNAME="" UNITNAME="GUITools" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\NonVisual.cpp" FORMNAME="NonVisualDataModule" UNITNAME="NonVisual" CONTAINERID="CCompiler" DESIGNCLASS="TDataModule" LOCALCOMMAND=""/>
@@ -77,6 +79,7 @@
       <FILE FILENAME="windows\QueueController.cpp" FORMNAME="" UNITNAME="QueueController" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\ScpCommander.cpp" FORMNAME="ScpCommanderForm" UNITNAME="ScpCommander" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="forms\ScpExplorer.cpp" FORMNAME="ScpExplorerForm" UNITNAME="ScpExplorer" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="windows\SynchronizeController.cpp" FORMNAME="" UNITNAME="SynchronizeController" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\TerminalManager.cpp" FORMNAME="" UNITNAME="TerminalManager" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\Tools.cpp" FORMNAME="" UNITNAME="Tools.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="windows\UserInterface.cpp" FORMNAME="" UNITNAME="UserInterface" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
@@ -99,8 +102,8 @@ IncludeVerInfo=1
 AutoIncBuild=1
 MajorVer=3
 MinorVer=6
-Release=6
-Build=234
+Release=7
+Build=239
 Debug=0
 PreRelease=0
 Special=0
@@ -112,13 +115,13 @@ CodePage=1252
 [Version Info Keys]
 CompanyName=Martin Prikryl
 FileDescription=Windows SCP/SFTP client
-FileVersion=3.6.6.234
+FileVersion=3.6.7.239
 InternalName=winscp3
 LegalCopyright=(c) 2000-2004 Martin Prikryl
 LegalTrademarks=
-OriginalFilename=winscp366.exe
+OriginalFilename=winscp367.exe
 ProductName=WinSCP
-ProductVersion=3.6.6.0
+ProductVersion=3.6.7.0
 WWW=http://winscp.sourceforge.net/
 
 [Compiler]

+ 2 - 2
WinSCP3.drc

@@ -288,7 +288,7 @@
 #define Comboedit_SBrowse 65498
 #define Comboedit_SDefaultFilter 65499
 #define Comboedit_SInvalidFileName 65500
-#define DiscMon_16392 65501
+#define Discmon_STooManyWatchDirectories 65501
 #define HelpIntfs_16398 65502
 #define HelpIntfs_16400 65503
 #define Dirviewcolproperties_SDirViewSizeCol 65504
@@ -606,7 +606,7 @@ BEGIN
 	Comboedit_SBrowse,	"Browse"
 	Comboedit_SDefaultFilter,	"All files (*.*)|*.*"
 	Comboedit_SInvalidFileName,	"Invalid file name - %s"
-	DiscMon_16392,	"Cannot watch for changes in %d directories and subdirectories (limit is %d)."
+	Discmon_STooManyWatchDirectories,	"Cannot watch for changes in more then %d directories and subdirectories."
 	HelpIntfs_16398,	"Unable to find a Table of Contents"
 	HelpIntfs_16400,	"No help found for %s"
 	Dirviewcolproperties_SDirViewSizeCol,	"Size"

BIN
WinSCP3.res


+ 6 - 0
components/UnixDriveView.cpp

@@ -56,7 +56,9 @@ __fastcall TCustomUnixDriveView::~TCustomUnixDriveView()
   Terminal = NULL;
   if (FDummyDragFile != NULL)
   {
+    #ifndef DESIGN_ONLY
     SAFE_DESTROY(FDummyDragFile);
+    #endif
   }
 }
 //---------------------------------------------------------------------------
@@ -351,11 +353,13 @@ TRemoteFile * __fastcall TCustomUnixDriveView::NodeFileForce(TTreeNode * Node)
 
   if (File == NULL)
   {
+    #ifndef DESIGN_ONLY
     SAFE_DESTROY(FDummyDragFile);
     FDummyDragFile = new TRemoteDirectoryFile();
     FDummyDragFile->FileName = Node->Text;
     FDummyDragFile->FullFileName = NodePathName(Node);
     File = FDummyDragFile;
+    #endif
   }
 
   return File;
@@ -521,10 +525,12 @@ AnsiString __fastcall TCustomUnixDriveView::NodePathName(TTreeNode * Node)
 //---------------------------------------------------------------------------
 void __fastcall TCustomUnixDriveView::ClearDragFileList(TFileList * FileList)
 {
+  #ifndef DESIGN_ONLY
   if (FDummyDragFile != NULL)
   {
     SAFE_DESTROY(FDummyDragFile);
   }
+  #endif
   TCustomDriveView::ClearDragFileList(FileList);
 }
 //---------------------------------------------------------------------------

+ 0 - 13
core/Common.cpp

@@ -102,19 +102,6 @@ void PackStr(AnsiString &Str)
   Str = Str.c_str();
 }
 //---------------------------------------------------------------------------
-AnsiString GetTemporaryPath()
-{
-  AnsiString Path;
-  Path.SetLength(255);
-  GetTempPath(Path.Length(), Path.c_str());
-  PackStr(Path);
-  if (!Path.IsPathDelimiter(Path.Length()))
-  {
-    Path += '\\';
-  }
-  return Path;
-}
-//---------------------------------------------------------------------------
 AnsiString MakeValidFileName(AnsiString FileName)
 {
   AnsiString IllegalChars = ";,=+<>|\"[] \\/?*";

+ 0 - 1
core/Common.h

@@ -22,7 +22,6 @@ extern const char EngShortMonthNames[12][4];
 AnsiString ReplaceChar(AnsiString Str, Char A, Char B);
 AnsiString DeleteChar(AnsiString Str, Char C);
 void PackStr(AnsiString &Str);
-AnsiString GetTemporaryPath();
 AnsiString MakeValidFileName(AnsiString FileName);
 AnsiString RootKeyToStr(HKEY RootKey);
 AnsiString BooleanToStr(bool B);

+ 3 - 3
core/Configuration.cpp

@@ -554,9 +554,9 @@ TStorage __fastcall TConfiguration::GetStorage()
 void __fastcall TConfiguration::SetRandomSeedFile(AnsiString value)
 {
   char *seedpath = seedpath_ptr();
-  if (value.Length() > seedpath_size())
+  if (value.Length() >= seedpath_size())
   {
-    value.SetLength(seedpath_size());
+    value.SetLength(seedpath_size() - 1);
   }
   strcpy(seedpath, StripPathQuotes(value).c_str());
 }
@@ -626,7 +626,7 @@ bool __fastcall TConfiguration::GetLogWindowComplete()
 //---------------------------------------------------------------------
 AnsiString __fastcall TConfiguration::GetDefaultLogFileName()
 {
-  return GetTemporaryPath() + "winscp.log";
+  return IncludeTrailingBackslash(SystemTemporaryDirectory()) + "winscp.log";
 }
 //---------------------------------------------------------------------------
 void __fastcall TConfiguration::SetConfirmOverwriting(bool value)

+ 2 - 2
core/Net.cpp

@@ -26,7 +26,7 @@ void __fastcall NetInitialize()
   InitWinsock();
   sk_init();
   AnsiString VersionString = SshVersionString();
-  assert(!VersionString.IsEmpty() && VersionString.Length() < 40);
+  assert(!VersionString.IsEmpty() && VersionString.Length() < 50);
   strcpy(sshver, VersionString.c_str());
 }
 //---------------------------------------------------------------------------
@@ -98,7 +98,7 @@ static int get_line(void * frontend, const char * prompt, char * str,
   bool Result = SecureShell->PromptUser(prompt, Response, is_pw);
   if (Result)
   {
-    strcpy(str, Response.SubString(1, maxlen).c_str());
+    strcpy(str, Response.SubString(1, maxlen - 1).c_str());
   }
 
   return Result ? 1 : 0;

+ 3 - 2
core/PuttyIntf.c

@@ -18,7 +18,7 @@
 #include <misc.h>
 #include <storage.h>
 //---------------------------------------------------------------------------
-char sshver[40];
+char sshver[50];
 //---------------------------------------------------------------------------
 void SSHLogEvent(void * frontend, char * string);
 void SSHFatalError(char * string);
@@ -34,7 +34,8 @@ long RegCreateWinSCPKey(HKEY hKey, const char * lpSubKey, HKEY * phkResult);
   va_list ap; \
   char stuff[200]; \
   va_start(ap, FMT); \
-  vsprintf(stuff, FMT, ap); \
+  vsnprintf(stuff, sizeof(stuff), FMT, ap); \
+  stuff[sizeof(stuff) - 1] = '\0'; \
   va_end(ap);
 
 #define FATAL_BOX(FMT) \

+ 1 - 0
core/PuttyIntf.h

@@ -88,6 +88,7 @@ extern const struct ssh2_ciphers ssh2_des;
 extern const struct ssh2_ciphers ssh2_aes;
 extern const struct ssh2_ciphers ssh2_blowfish;
 //---------------------------------------------------------------------------
+#define MPEXT
 #include "Putty.h"
 #include <SSH.h>
 #include <Proxy.h>

+ 17 - 76
core/Queue.cpp

@@ -47,7 +47,6 @@ protected:
     Exception * E;
   };
 
-  bool FMasterPasswordTried;
   TTerminalQueue * FQueue;
   TTerminal * FTerminal;
   TQueueItem * FItem;
@@ -74,29 +73,6 @@ protected:
     TCancelStatus & Cancel);
 };
 //---------------------------------------------------------------------------
-typedef int __fastcall (__closure *TDirectoryAffected)
-  (TTerminal * Terminal, const AnsiString Directory);
-//---------------------------------------------------------------------------
-class TSecondaryTerminal : public TTerminal
-{
-public:
-  __fastcall TSecondaryTerminal(TTerminal * MainTerminal);
-
-  __property TDirectoryAffected OnDirectoryAffected = { read = FOnDirectoryAffected,
-    write = FOnDirectoryAffected };
-
-protected:
-  virtual void __fastcall DirectoryLoaded(TRemoteFileList * FileList);
-  virtual void __fastcall DirectoryModified(const AnsiString Path,
-    bool SubDirs);
-
-private:
-  TTerminal * FMainTerminal;
-  TDirectoryAffected FOnDirectoryAffected;
-
-  void __fastcall DoDirectoryAffected(const AnsiString Path);
-};
-//---------------------------------------------------------------------------
 // TSignalThread
 //---------------------------------------------------------------------------
 int __fastcall ThreadProc(void * Thread)
@@ -216,7 +192,6 @@ __fastcall TTerminalQueue::TTerminalQueue(TTerminal * Terminal,
   assert(Terminal != NULL);
   FSessionData = new TSessionData("");
   FSessionData->Assign(Terminal->SessionData);
-  FSessionData->NonPersistant();
 
   FItems = new TList();
   FTerminals = new TList();
@@ -668,29 +643,6 @@ bool __fastcall TTerminalQueue::GetIsEmpty()
   return (FItems->Count == 0);
 }
 //---------------------------------------------------------------------------
-// TSecondaryTerminal
-//---------------------------------------------------------------------------
-__fastcall TSecondaryTerminal::TSecondaryTerminal(TTerminal * MainTerminal) :
-  TTerminal(), FMainTerminal(MainTerminal)
-{
-  assert(FMainTerminal != NULL);
-  OnDirectoryAffected = NULL;
-  UseBusyCursor = false;
-}
-//---------------------------------------------------------------------------
-void __fastcall TSecondaryTerminal::DirectoryLoaded(TRemoteFileList * FileList)
-{
-  FMainTerminal->DirectoryLoaded(FileList);
-  assert(FileList != NULL);
-}
-//---------------------------------------------------------------------------
-void __fastcall TSecondaryTerminal::DirectoryModified(const AnsiString Path,
-  bool SubDirs)
-{
-  // clear cache of main terminal
-  FMainTerminal->DirectoryModified(Path, SubDirs);
-}
-//---------------------------------------------------------------------------
 // TTerminalItem
 //---------------------------------------------------------------------------
 __fastcall TTerminalItem::TTerminalItem(TTerminalQueue * Queue) :
@@ -702,6 +654,8 @@ __fastcall TTerminalItem::TTerminalItem(TTerminalQueue * Queue) :
   FTerminal = new TSecondaryTerminal(FQueue->FTerminal);
   try
   {
+    FTerminal->UseBusyCursor = false;
+    
     FTerminal->Configuration = Queue->FConfiguration;
     FTerminal->SessionData = Queue->FSessionData;
 
@@ -759,7 +713,6 @@ void __fastcall TTerminalItem::ProcessEvent()
     {
       FItem->SetStatus(TQueueItem::qsConnecting);
 
-      FMasterPasswordTried = false;
       FTerminal->SessionData->RemoteDirectory = FItem->StartupDirectory();
       FTerminal->Open();
       FTerminal->DoStartup();
@@ -905,34 +858,17 @@ void __fastcall TTerminalItem::TerminalQueryUser(TObject * Sender,
 void __fastcall TTerminalItem::TerminalPromptUser(TSecureShell * SecureShell,
   AnsiString Prompt, TPromptKind Kind, AnsiString & Response, bool & Result)
 {
-  Result = false;
-  
-  if (!FMasterPasswordTried)
-  {
-    // let's expect that the main session is already authenticated and its password
-    // is not written after, so no locking is necessary
-    Response = FQueue->FTerminal->Password;
-    if (!Response.IsEmpty())
-    {
-      Result = true;
-    }
-    FMasterPasswordTried = true;
-  }
+  TPromptUserRec PromptUserRec;
+  PromptUserRec.SecureShell = SecureShell;
+  PromptUserRec.Prompt = Prompt;
+  PromptUserRec.Kind = Kind;
+  PromptUserRec.Response = Response;
+  PromptUserRec.Result = Result;
 
-  if (!Result)
+  if (WaitForUserAction(TQueueItem::qsPrompt, &PromptUserRec))
   {
-    TPromptUserRec PromptUserRec;
-    PromptUserRec.SecureShell = SecureShell;
-    PromptUserRec.Prompt = Prompt;
-    PromptUserRec.Kind = Kind;
-    PromptUserRec.Response = Response;
-    PromptUserRec.Result = Result;
-
-    if (WaitForUserAction(TQueueItem::qsPrompt, &PromptUserRec))
-    {
-      Response = PromptUserRec.Response;
-      Result = PromptUserRec.Result;
-    }
+    Response = PromptUserRec.Response;
+    Result = PromptUserRec.Result;
   }
 }
 //---------------------------------------------------------------------------
@@ -980,7 +916,7 @@ void __fastcall TTerminalItem::OperationProgress(
 //---------------------------------------------------------------------------
 __fastcall TQueueItem::TQueueItem() :
   FStatus(qsPending), FTerminalItem(NULL), FSection(NULL), FProgressData(NULL),
-  FQueue(NULL), FInfo(NULL)
+  FQueue(NULL), FInfo(NULL), FCompleteEvent(INVALID_HANDLE_VALUE)
 {
   FSection = new TCriticalSection();
   FInfo = new TInfo();
@@ -988,6 +924,11 @@ __fastcall TQueueItem::TQueueItem() :
 //---------------------------------------------------------------------------
 __fastcall TQueueItem::~TQueueItem()
 {
+  if (FCompleteEvent != INVALID_HANDLE_VALUE)
+  {
+    SetEvent(FCompleteEvent);
+  }
+
   delete FSection;
   delete FInfo;
 }

+ 2 - 0
core/Queue.h

@@ -130,6 +130,7 @@ public:
   static bool __fastcall IsUserActionStatus(TStatus Status);
 
   __property TStatus Status = { read = GetStatus };
+  __property HANDLE CompleteEvent = { read = FCompleteEvent, write = FCompleteEvent };
 
 protected:
   TStatus FStatus;
@@ -138,6 +139,7 @@ protected:
   TFileOperationProgressType * FProgressData;
   TQueueItem::TInfo * FInfo;
   TTerminalQueue * FQueue;
+  HANDLE FCompleteEvent;
 
   __fastcall TQueueItem();
   virtual __fastcall ~TQueueItem();

+ 23 - 1
core/RemoteFiles.cpp

@@ -204,6 +204,7 @@ __fastcall TRemoteFile::TRemoteFile(TRemoteFile * ALinkedByFile):
   FLinkedByFile = ALinkedByFile;
   FTerminal = NULL;
   FDirectory = NULL;
+  FIsHidden = -1;
 }
 //---------------------------------------------------------------------------
 __fastcall TRemoteFile::~TRemoteFile()
@@ -275,7 +276,28 @@ Integer __fastcall TRemoteFile::GetIconIndex()
 //---------------------------------------------------------------------------
 Boolean __fastcall TRemoteFile::GetIsHidden()
 {
-  return IsUnixHiddenFile(FileName);
+  bool Result;
+  switch (FIsHidden)
+  {
+    case 0:
+      Result = false;
+      break;
+
+    case 1:
+      Result = true;
+      break;
+
+    default:
+      Result = IsUnixHiddenFile(FileName);
+      break;
+  }
+
+  return Result;
+}
+//---------------------------------------------------------------------------
+void __fastcall TRemoteFile::SetIsHidden(bool value)
+{
+  FIsHidden = value ? 1 : 0;
 }
 //---------------------------------------------------------------------------
 Boolean __fastcall TRemoteFile::GetIsDirectory() const

+ 3 - 1
core/RemoteFiles.h

@@ -38,6 +38,7 @@ private:
   bool FSelected;
   bool FCyclicLink;
   AnsiString FFullFileName;
+  int FIsHidden;
   int __fastcall GetAttr();
   bool __fastcall GetBrokenLink();
   bool __fastcall GetIsDirectory() const;
@@ -55,6 +56,7 @@ private:
   AnsiString __fastcall GetFullFileName();
   int __fastcall GetIconIndex();
   bool __fastcall GetIsHidden();
+  void __fastcall SetIsHidden(bool value);
   bool __fastcall GetIsParentDirectory();
   bool __fastcall GetIsThisDirectory();
   bool __fastcall GetIsInaccesibleDirectory();
@@ -97,7 +99,7 @@ public:
   __property bool Selected  = { read=FSelected, write=FSelected };
   __property AnsiString FullFileName  = { read = GetFullFileName, write = FFullFileName };
   __property int IconIndex = { read = GetIconIndex };
-  __property bool IsHidden = { read = GetIsHidden };
+  __property bool IsHidden = { read = GetIsHidden, write = SetIsHidden };
   __property bool IsParentDirectory = { read = GetIsParentDirectory };
   __property bool IsThisDirectory = { read = GetIsThisDirectory };
   __property bool IsInaccesibleDirectory  = { read=GetIsInaccesibleDirectory };

+ 1 - 1
core/ScpFileSystem.cpp

@@ -191,7 +191,7 @@ bool __fastcall TCommandSet::GetOneLineCommand(TFSCommand /*Cmd*/)
 void __fastcall TCommandSet::SetCommands(TFSCommand Cmd, AnsiString value)
 {
   CHECK_CMD;
-  strcpy(CommandSet[Cmd].Command, value.SubString(1, MaxCommandLen).c_str());
+  strcpy(CommandSet[Cmd].Command, value.SubString(1, MaxCommandLen - 1).c_str());
 }
 //---------------------------------------------------------------------------
 AnsiString __fastcall TCommandSet::GetCommands(TFSCommand Cmd)

+ 34 - 6
core/SecureShell.cpp

@@ -101,7 +101,8 @@ void __fastcall TSecureShell::Open()
   SessionData->StoreToConfig(FConfig);
 
   InitError = FBackend->init(this, &FBackendHandle, FConfig,
-    SessionData->HostName.c_str(), SessionData->PortNumber, &RealHost, 0);
+    SessionData->HostName.c_str(), SessionData->PortNumber, &RealHost, 0,
+    FConfig->tcp_keepalives);
   if (InitError)
   {
     FatalError(InitError);
@@ -1008,7 +1009,7 @@ TLogLineType __fastcall TSessionLog::GetType(Integer Index)
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TSessionLog::Add(TLogLineType aType, AnsiString aLine)
+void __fastcall TSessionLog::DoAdd(bool Formatted, TLogLineType aType, AnsiString aLine)
 {
   assert(Configuration);
   if (IsLogging())
@@ -1025,18 +1026,34 @@ void __fastcall TSessionLog::Add(TLogLineType aType, AnsiString aLine)
         while (!aLine.IsEmpty())
         {
           AnsiString NewStr;
-          NewStr = AnsiString(LogLineMarks[aType]) + CutToChar(aLine, '\n', False);
+          AnsiString FileStr;
+          
+          if (Formatted)
+          {
+            assert(aLine.Length() >= 2);
+            FileStr = aLine;
+            NewStr = aLine;
+            NewStr.Delete(2, 1);
+            aLine = "";
+          }
+          else
+          {
+            NewStr = AnsiString(LogLineMarks[aType]) + CutToChar(aLine, '\n', False);
+            FileStr = NewStr;
+            FileStr.Insert(' ', 2);
+          }
+
           if (Configuration->Logging)
           {
             TStringList::Add(NewStr);
             FLoggedLines++;
           }
-          NewStr.Insert(' ', 2);
-          DoAddLine(NewStr);
+
+          DoAddLine(FileStr);
           if (Configuration->Logging && Configuration->LogToFile)
           {
             if (!FFile) OpenLogFile();
-            if (FFile) fprintf((FILE *)FFile, "%s\n", NewStr.c_str());
+            if (FFile) fprintf((FILE *)FFile, "%s\n", FileStr.c_str());
           }
         }
         if (Configuration->Logging)
@@ -1069,6 +1086,17 @@ void __fastcall TSessionLog::Add(TLogLineType aType, AnsiString aLine)
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TSessionLog::Add(TLogLineType aType, AnsiString aLine)
+{
+  DoAdd(false, aType, aLine);
+}
+//---------------------------------------------------------------------------
+void __fastcall TSessionLog::AddFromOtherLog(TObject * /*Sender*/,
+  const AnsiString AddedLine)
+{
+  DoAdd(true, llMessage, AddedLine);
+}
+//---------------------------------------------------------------------------
 void __fastcall TSessionLog::AddException(Exception * E)
 {
   if (E)

+ 3 - 1
core/SecureShell.h

@@ -66,6 +66,7 @@ private:
   void __fastcall SetEnabled(bool value);
   void __fastcall SetConfiguration(TConfiguration * value);
   AnsiString __fastcall GetSessionName();
+  inline void __fastcall DoAdd(bool Formatted, TLogLineType aType, AnsiString aLine);
 
 public:
   __fastcall TSessionLog(TSecureShell * AOwner);
@@ -74,6 +75,7 @@ public:
   void __fastcall AddStartupInfo();
   void __fastcall AddException(Exception * E);
   void __fastcall AddSeparator();
+  void __fastcall AddFromOtherLog(TObject * Sender, const AnsiString AddedLine);
   virtual void __fastcall Clear();
   void __fastcall ReflectSettings();
   bool __fastcall inline IsLogging()
@@ -150,7 +152,6 @@ private:
   TCipher __fastcall FuncToSsh2Cipher(const void * Cipher) const;
   TCompressionType __fastcall FuncToCompression(const void * Compress) const;
   void __fastcall Init();
-  void __fastcall SetSessionData(TSessionData * value);
   void __fastcall SetActive(bool value);
   bool __fastcall GetActive() const;
   TCipher __fastcall GetCSCipher();
@@ -177,6 +178,7 @@ protected:
   void __fastcall GotHostKey();
   unsigned long __fastcall MaxPacketSize();
   virtual void __fastcall KeepAlive();
+  virtual void __fastcall SetSessionData(TSessionData * value);
 
 public:
   __fastcall TSecureShell();

+ 12 - 1
core/SessionData.cpp

@@ -102,6 +102,7 @@ void __fastcall TSessionData::Default()
   SFTPUploadQueue = 4;
   SFTPListingQueue = 2;
   SFTPSymlinkBug = asAuto;
+  SFTPMaxVersion = 5;
 
   CustomParam1 = "";
   CustomParam2 = "";
@@ -187,6 +188,7 @@ void __fastcall TSessionData::Assign(TPersistent * Source)
     DUPL(SFTPUploadQueue);
     DUPL(SFTPListingQueue);
     DUPL(SFTPSymlinkBug);
+    DUPL(SFTPMaxVersion);
 
     DUPL(CustomParam1);
     DUPL(CustomParam2);
@@ -311,6 +313,7 @@ void __fastcall TSessionData::StoreToConfig(void * config)
 
   // permanent settings
   cfg->nopty = TRUE;
+  cfg->tcp_keepalives = 0;
 }
 //---------------------------------------------------------------------
 void __fastcall TSessionData::Load(THierarchicalStorage * Storage)
@@ -430,6 +433,7 @@ void __fastcall TSessionData::Load(THierarchicalStorage * Storage)
     }
 
     SFTPSymlinkBug = TAutoSwitch(Storage->ReadInteger("SFTPSymlinkBug", SFTPSymlinkBug));
+    SFTPMaxVersion = Storage->ReadInteger("SFTPMaxVersion", SFTPMaxVersion);
 
     // read only (used only on Import from Putty dialog)
     ProtocolStr = Storage->ReadString("Protocol", ProtocolStr);
@@ -590,6 +594,7 @@ void __fastcall TSessionData::Save(THierarchicalStorage * Storage,
     if (!PuttyExport)
     {
       WRITE_DATA(Integer, SFTPSymlinkBug);
+      WRITE_DATA(Integer, SFTPMaxVersion);
 
       WRITE_DATA(String, CustomParam1);
       WRITE_DATA(String, CustomParam2);
@@ -937,7 +942,8 @@ void __fastcall TSessionData::SetPublicKeyFile(AnsiString value)
 //---------------------------------------------------------------------
 AnsiString __fastcall TSessionData::GetDefaultLogFileName()
 {
-  return GetTemporaryPath() + MakeValidFileName(SessionName) + ".log";
+  return IncludeTrailingBackslash(SystemTemporaryDirectory()) +
+    MakeValidFileName(SessionName) + ".log";
 }
 //---------------------------------------------------------------------
 void __fastcall TSessionData::SetReturnVar(AnsiString value)
@@ -1209,6 +1215,11 @@ void __fastcall TSessionData::SetSFTPListingQueue(int value)
   SET_SESSION_PROPERTY(SFTPListingQueue);
 }
 //---------------------------------------------------------------------
+void __fastcall TSessionData::SetSFTPMaxVersion(int value)
+{
+  SET_SESSION_PROPERTY(SFTPMaxVersion);
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::SetSFTPSymlinkBug(TAutoSwitch value)
 {
   SET_SESSION_PROPERTY(SFTPSymlinkBug);

+ 3 - 0
core/SessionData.h

@@ -90,6 +90,7 @@ private:
   int FSFTPDownloadQueue;
   int FSFTPUploadQueue;
   int FSFTPListingQueue;
+  int FSFTPMaxVersion;
   bool FConsiderDST;
   TAutoSwitch FSFTPSymlinkBug;
 
@@ -167,6 +168,7 @@ private:
   void __fastcall SetSFTPDownloadQueue(int value);
   void __fastcall SetSFTPUploadQueue(int value);
   void __fastcall SetSFTPListingQueue(int value);
+  void __fastcall SetSFTPMaxVersion(int value);
   void __fastcall SetSFTPSymlinkBug(TAutoSwitch value);
   AnsiString __fastcall GetStorageKey();
   void __fastcall SetConsiderDST(bool value);
@@ -254,6 +256,7 @@ public:
   __property int SFTPDownloadQueue = { read = FSFTPDownloadQueue, write = SetSFTPDownloadQueue };
   __property int SFTPUploadQueue = { read = FSFTPUploadQueue, write = SetSFTPUploadQueue };
   __property int SFTPListingQueue = { read = FSFTPListingQueue, write = SetSFTPListingQueue };
+  __property int SFTPMaxVersion = { read = FSFTPMaxVersion, write = SetSFTPMaxVersion };
   __property TAutoSwitch SFTPSymlinkBug = { read = FSFTPSymlinkBug, write = SetSFTPSymlinkBug };
   __property bool ConsiderDST = { read = FConsiderDST, write = SetConsiderDST };
   __property AnsiString StorageKey = { read = GetStorageKey };

+ 122 - 10
core/SftpFileSystem.cpp

@@ -26,8 +26,11 @@
 #define SSH_FILEXFER_ATTR_ACCESSTIME        0x00000008
 #define SSH_FILEXFER_ATTR_CREATETIME        0x00000010
 #define SSH_FILEXFER_ATTR_MODIFYTIME        0x00000020
+#define SSH_FILEXFER_ATTR_ACL               0x00000040
 #define SSH_FILEXFER_ATTR_OWNERGROUP        0x00000080
 #define SSH_FILEXFER_ATTR_SUBSECOND_TIMES   0x00000100
+#define SSH_FILEXFER_ATTR_BITS              0x00000200
+#define SSH_FILEXFER_ATTR_EXTENDED          0x80000000
 
 #define SSH_FILEXFER_ATTR_COMMON \
   (SSH_FILEXFER_ATTR_SIZE | SSH_FILEXFER_ATTR_OWNERGROUP | \
@@ -42,6 +45,39 @@
 
 #define SSH_FXF_TEXT            0x00000040
 
+#define SSH_FXF_ACCESS_DISPOSITION        0x00000007
+#define     SSH_FXF_CREATE_NEW            0x00000000
+#define     SSH_FXF_CREATE_TRUNCATE       0x00000001
+#define     SSH_FXF_OPEN_EXISTING         0x00000002
+#define     SSH_FXF_OPEN_OR_CREATE        0x00000003
+#define     SSH_FXF_TRUNCATE_EXISTING     0x00000004
+#define SSH_FXF_ACCESS_APPEND_DATA        0x00000008
+#define SSH_FXF_ACCESS_APPEND_DATA_ATOMIC 0x00000010
+#define SSH_FXF_ACCESS_TEXT_MODE          0x00000020
+#define SSH_FXF_ACCESS_READ_LOCK          0x00000040
+#define SSH_FXF_ACCESS_WRITE_LOCK         0x00000080
+#define SSH_FXF_ACCESS_DELETE_LOCK        0x00000100
+
+#define ACE4_READ_DATA         0x00000001
+#define ACE4_LIST_DIRECTORY    0x00000001
+#define ACE4_WRITE_DATA        0x00000002
+#define ACE4_ADD_FILE          0x00000002
+#define ACE4_APPEND_DATA       0x00000004
+#define ACE4_ADD_SUBDIRECTORY  0x00000004
+#define ACE4_READ_NAMED_ATTRS  0x00000008
+#define ACE4_WRITE_NAMED_ATTRS 0x00000010
+#define ACE4_EXECUTE           0x00000020
+#define ACE4_DELETE_CHILD      0x00000040
+#define ACE4_READ_ATTRIBUTES   0x00000080
+#define ACE4_WRITE_ATTRIBUTES  0x00000100
+#define ACE4_DELETE            0x00010000
+#define ACE4_READ_ACL          0x00020000
+#define ACE4_WRITE_ACL         0x00040000
+#define ACE4_WRITE_OWNER       0x00080000
+#define ACE4_SYNCHRONIZE       0x00100000
+
+#define SSH_FILEXFER_ATTR_FLAGS_HIDDEN           0x00000004
+
 #define SFTP_MAX_PACKET_LEN   102400
 //---------------------------------------------------------------------------
 #define SFTP_EXT_WINSCP "[email protected]"
@@ -56,7 +92,7 @@
 #define OGQ_LIST_GROUPS 0x02
 //---------------------------------------------------------------------------
 const int SFTPMinVersion = 0;
-const int SFTPMaxVersion = 4;
+const int SFTPMaxVersion = 5;
 const int SFTPNoMessageNumber = -1;
 
 const int asNo =            0;
@@ -362,7 +398,9 @@ public:
     if (Version >= 4)
     {
       char FXType = GetByte();
-      static char Types[] = "-DLSU";
+      // -:regular, D:directory, L:symlink, S:special, U:unknown
+      // O:socket, C:char devide, B:block device, F:fifo 
+      static char* Types = "-DLSUOCBF";
       if (FXType < 1 || FXType > (char)strlen(Types))
       {
         throw Exception(FMTLOAD(SFTP_UNKNOWN_FILE_TYPE, (int(FXType))));
@@ -433,6 +471,21 @@ public:
       }
     }
 
+    if (Flags & SSH_FILEXFER_ATTR_ACL)
+    {
+      GetString();
+    }
+
+    if (Flags & SSH_FILEXFER_ATTR_BITS)
+    {
+      assert(Version >= 5);
+      unsigned long Bits = GetCardinal();
+      if (FLAGSET(Bits, SSH_FILEXFER_ATTR_FLAGS_HIDDEN))
+      {
+        File->IsHidden = true;
+      }
+    }
+
     if ((Version < 4) && (Type != SSH_FXP_ATTRS))
     {
       try
@@ -1268,6 +1321,9 @@ unsigned long __fastcall TSFTPFileSystem::GotStatusPacket(TSFTPPacket * Packet,
     SFTP_STATUS_FILE_ALREADY_EXISTS,
     SFTP_STATUS_WRITE_PROTECT,
     SFTP_STATUS_NO_MEDIA,
+    SFTP_STATUS_NO_SPACE_ON_FILESYSTEM,
+    SFTP_STATUS_QUOTA_EXCEEDED,
+    SFTP_STATUS_UNKNOWN_PRINCIPLE
   };
   int Message;
   if ((AllowStatus & (0x01 << Code)) == 0)
@@ -1282,26 +1338,38 @@ unsigned long __fastcall TSFTPFileSystem::GotStatusPacket(TSFTPPacket * Packet,
     }
     AnsiString ServerMessage;
     AnsiString LanguageTag;
+    AnsiString AdditionalInfo;
     if (FVersion >= 3)
     {
       ServerMessage = DecodeUTF(Packet->GetString());
       LanguageTag = Packet->GetString();
+      if ((FVersion >= 5) && (Message == SFTP_STATUS_UNKNOWN_PRINCIPLE))
+      {
+        while (Packet->NextData != NULL)
+        {
+          if (!AdditionalInfo.IsEmpty())
+          {
+            AdditionalInfo += ", ";
+          }
+          AdditionalInfo += Packet->GetString();
+        }
+      }
     }
     else
     {
       ServerMessage = LoadStr(SFTP_SERVER_MESSAGE_UNSUPPORTED);
     }
-    if (LanguageTag.IsEmpty())
-    {
-      LanguageTag = "*";
-    }
     if (FTerminal->IsLogging())
     {
       FTerminal->Log->Add(llOutput, FORMAT("Status/error code: %d, Message: %d, Server: %s, Language: %s ",
         (int(Code), (int)Packet->MessageNumber, ServerMessage, LanguageTag)));
     }
-    AnsiString Error = FMTLOAD(SFTP_ERROR_FORMAT, (LoadStr(Message), int(Code),
-      ServerMessage, LanguageTag, int(Packet->RequestType)));
+    if (!LanguageTag.IsEmpty())
+    {
+      LanguageTag = FORMAT("(%s)", (LanguageTag));
+    }
+    AnsiString Error = FMTLOAD(SFTP_ERROR_FORMAT, (LoadStr(Message) + AdditionalInfo,
+      int(Code), ServerMessage, LanguageTag, int(Packet->RequestType)));
     FTerminal->TerminalError(NULL, Error);
     return 0;
   }
@@ -1683,7 +1751,12 @@ AnsiString __fastcall TSFTPFileSystem::GetCurrentDirectory()
 void __fastcall TSFTPFileSystem::DoStartup()
 {
   TSFTPPacket Packet(SSH_FXP_INIT);
-  Packet.AddCardinal(SFTPMaxVersion);
+  int MaxVersion = FTerminal->SessionData->SFTPMaxVersion;
+  if (MaxVersion > SFTPMaxVersion)
+  {
+    MaxVersion = SFTPMaxVersion;
+  }
+  Packet.AddCardinal(MaxVersion);
 
   try
   {
@@ -2222,6 +2295,10 @@ void __fastcall TSFTPFileSystem::RenameFile(const AnsiString FileName,
     TargetName = NewName;
   }
   Packet.AddString(TargetName);
+  if (FVersion >= 5)
+  {
+    Packet.AddCardinal(0);
+  }
   SendPacketAndReceiveResponse(&Packet, &Packet, SSH_FXP_STATUS);
 }
 //---------------------------------------------------------------------------
@@ -2775,7 +2852,42 @@ AnsiString __fastcall TSFTPFileSystem::SFTPOpenRemoteFile(
   TSFTPPacket Packet(SSH_FXP_OPEN);
 
   Packet.AddString(FileName);
-  Packet.AddCardinal(OpenType);
+  if (FVersion < 5)
+  {
+    Packet.AddCardinal(OpenType);
+  }
+  else
+  {
+    unsigned long Access =
+      FLAGMASK(FLAGSET(OpenType, SSH_FXF_READ), ACE4_READ_DATA) |
+      FLAGMASK(FLAGSET(OpenType, SSH_FXF_WRITE), ACE4_WRITE_DATA | ACE4_APPEND_DATA);
+
+    unsigned long Flags;
+
+    if (FLAGSET(OpenType, SSH_FXF_CREAT | SSH_FXF_EXCL))
+    {
+      Flags = SSH_FXF_CREATE_NEW;
+    }
+    else if (FLAGSET(OpenType, SSH_FXF_CREAT | SSH_FXF_TRUNC))
+    {
+      Flags = SSH_FXF_CREATE_TRUNCATE;
+    }
+    else if (FLAGSET(OpenType, SSH_FXF_CREAT))
+    {
+      Flags = SSH_FXF_OPEN_OR_CREATE;
+    }
+    else
+    {
+      Flags = SSH_FXF_OPEN_EXISTING;
+    }
+
+    Flags |=
+      FLAGMASK(FLAGSET(OpenType, SSH_FXF_APPEND), SSH_FXF_ACCESS_APPEND_DATA) |
+      FLAGMASK(FLAGSET(OpenType, SSH_FXF_TEXT), SSH_FXF_ACCESS_TEXT_MODE);
+
+    Packet.AddCardinal(Access);
+    Packet.AddCardinal(Flags);
+  }
   Packet.AddProperties(NULL, NULL, NULL, NULL, NULL,
     Size >= 0 ? &Size : NULL, false, FVersion);
 

+ 168 - 4
core/Terminal.cpp

@@ -55,10 +55,13 @@ __fastcall TTerminal::TTerminal(): TSecureShell()
   FDirectoryCache = new TRemoteDirectoryCache();
   FDirectoryChangesCache = NULL;
   FFSProtocol = cfsUnknown;
+  FCommandSession = NULL;
 }
 //---------------------------------------------------------------------------
 __fastcall TTerminal::~TTerminal()
 {
+  SAFE_DESTROY(FCommandSession);
+
   if (SessionData->CacheDirectoryChanges && SessionData->PreserveDirectoryChanges &&
       (FDirectoryChangesCache != NULL))
   {
@@ -102,6 +105,11 @@ void __fastcall TTerminal::KeepAlive()
   {
     TSecureShell::KeepAlive();
   }
+
+  if (CommandSessionOpened)
+  {
+    FCommandSession->KeepAlive();
+  }
 }
 //---------------------------------------------------------------------------
 bool __fastcall TTerminal::IsAbsolutePath(const AnsiString Path)
@@ -139,6 +147,11 @@ void __fastcall TTerminal::Close()
 {
   // file system cannot be destoryed here, moved to destructor
   TSecureShell::Close();
+
+  if (CommandSessionOpened)
+  {
+    FCommandSession->Close();
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::Open()
@@ -467,6 +480,11 @@ void __fastcall TTerminal::BeginTransaction()
     FReadDirectoryPending = false;
   }
   FInTransaction++;
+
+  if (FCommandSession != NULL)
+  {
+    FCommandSession->BeginTransaction();
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::EndTransaction()
@@ -493,6 +511,13 @@ void __fastcall TTerminal::EndTransaction()
       }
     }
   }
+
+  if (FCommandSession != NULL)
+  {
+    // so far we do not require directory content to be loaded
+    FCommandSession->FReadDirectoryPending = false;
+    FCommandSession->EndTransaction();
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::SetExceptionOnFail(bool value)
@@ -504,6 +529,11 @@ void __fastcall TTerminal::SetExceptionOnFail(bool value)
       throw Exception("ExceptionOnFail is already zero.");
     FExceptionOnFail--;
   }
+
+  if (FCommandSession != NULL)
+  {
+    FCommandSession->FExceptionOnFail = FExceptionOnFail;
+  }
 }
 //---------------------------------------------------------------------------
 bool __fastcall TTerminal::GetExceptionOnFail() const
@@ -1140,8 +1170,27 @@ void __fastcall TTerminal::DoCustomCommandOnFile(AnsiString FileName,
 {
   try
   {
-    assert(FFileSystem);
-    FFileSystem->CustomCommandOnFile(FileName, File, Command, Params);
+    if (IsCapable[fcAnyCommand])
+    {
+      assert(FFileSystem);
+      FFileSystem->CustomCommandOnFile(FileName, File, Command, Params);
+    }
+    else
+    {
+      assert(CommandSessionOpened);
+      assert(FCommandSession->FSProtocol == cfsSCP);
+      LogEvent("Executing custom command on command session.");
+      FCommandSession->Log->OnAddLine = Log->AddFromOtherLog;
+      try
+      {
+        FCommandSession->CurrentDirectory = CurrentDirectory;
+        FCommandSession->FFileSystem->CustomCommandOnFile(FileName, File, Command, Params);
+      }
+      __finally
+      {
+        FCommandSession->Log->OnAddLine = NULL;
+      }
+    }
   }
   catch(Exception & E)
   {
@@ -1541,14 +1590,78 @@ bool __fastcall TTerminal::AllowedAnyCommand(const AnsiString Command)
   return !Command.Trim().IsEmpty();
 }
 //---------------------------------------------------------------------------
+bool __fastcall TTerminal::GetCommandSessionOpened()
+{
+  return (FCommandSession != NULL) && FCommandSession->Active;
+}
+//---------------------------------------------------------------------------
+TTerminal * __fastcall TTerminal::GetCommandSession()
+{
+  if ((FCommandSession != NULL) && !FCommandSession->Active)
+  {
+    SAFE_DESTROY(FCommandSession);
+  }
+
+  if (FCommandSession == NULL)
+  {
+    // transaction cannot be started yet to allow proper matching transation
+    // levels between main and command session  
+    assert(!FInTransaction);
+
+    try
+    {
+      FCommandSession = new TSecondaryTerminal(this);
+
+      FCommandSession->Configuration = Configuration;
+      FCommandSession->SessionData = SessionData;
+      FCommandSession->SessionData->RemoteDirectory = CurrentDirectory;
+      FCommandSession->SessionData->FSProtocol = fsSCPonly;
+
+      FCommandSession->FExceptionOnFail = FExceptionOnFail;
+
+      FCommandSession->OnQueryUser = OnQueryUser;
+      FCommandSession->OnPromptUser = OnPromptUser;
+      FCommandSession->OnShowExtendedException = OnShowExtendedException;
+      FCommandSession->OnProgress = OnProgress;
+      FCommandSession->OnFinished = OnFinished;
+    }
+    catch(...)
+    {
+      SAFE_DESTROY(FCommandSession);
+      throw;
+    }
+  }
+
+  return FCommandSession;
+}
+//---------------------------------------------------------------------------
 void __fastcall TTerminal::AnyCommand(const AnsiString Command)
 {
   assert(FFileSystem);
   try
   {
     DirectoryModified(CurrentDirectory, false);
-    LogEvent("Executing used defined command.");
-    FFileSystem->AnyCommand(Command);
+    if (IsCapable[fcAnyCommand])
+    {
+      LogEvent("Executing user defined command.");
+      FFileSystem->AnyCommand(Command);
+    }
+    else
+    {
+      assert(CommandSessionOpened);
+      assert(FCommandSession->FSProtocol == cfsSCP);
+      LogEvent("Executing user defined command on command session.");
+      FCommandSession->Log->OnAddLine = Log->AddFromOtherLog;
+      try
+      {
+        FCommandSession->CurrentDirectory = CurrentDirectory;
+        FCommandSession->FFileSystem->AnyCommand(Command);
+      }
+      __finally
+      {
+        FCommandSession->Log->OnAddLine = NULL;
+      }
+    }
     ReactOnCommand(fsAnyCommand);
   }
   catch (Exception &E)
@@ -2272,6 +2385,57 @@ bool __fastcall TTerminal::CopyToLocal(TStrings * FilesToCopy,
   return Result;
 }
 //---------------------------------------------------------------------------
+__fastcall TSecondaryTerminal::TSecondaryTerminal(TTerminal * MainTerminal) :
+  TTerminal(), FMainTerminal(MainTerminal), FMasterPasswordTried(false)
+{
+  assert(FMainTerminal != NULL);
+}
+//---------------------------------------------------------------------------
+void __fastcall TSecondaryTerminal::DirectoryLoaded(TRemoteFileList * FileList)
+{
+  FMainTerminal->DirectoryLoaded(FileList);
+  assert(FileList != NULL);
+}
+//---------------------------------------------------------------------------
+void __fastcall TSecondaryTerminal::DirectoryModified(const AnsiString Path,
+  bool SubDirs)
+{
+  // clear cache of main terminal
+  FMainTerminal->DirectoryModified(Path, SubDirs);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TSecondaryTerminal::DoPromptUser(AnsiString Prompt,
+  TPromptKind Kind, AnsiString & Response)
+{
+  bool Result = false;
+
+  if (!FMasterPasswordTried)
+  {
+    // let's expect that the main session is already authenticated and its password
+    // is not written after, so no locking is necessary
+    Response = FMainTerminal->Password;
+    if (!Response.IsEmpty())
+    {
+      Result = true;
+    }
+    FMasterPasswordTried = true;
+  }
+
+  if (!Result)
+  {
+    Result = TTerminal::DoPromptUser(Prompt, Kind, Response);
+  }
+
+  return Result;
+}
+//---------------------------------------------------------------------------
+void __fastcall TSecondaryTerminal::SetSessionData(TSessionData * value)
+{
+  TTerminal::SetSessionData(value);
+
+  SessionData->NonPersistant();
+}
+//---------------------------------------------------------------------------
 __fastcall TTerminalList::TTerminalList(TConfiguration * AConfiguration) :
   TObjectList()
 {

+ 23 - 0
core/Terminal.h

@@ -136,6 +136,7 @@ private:
   TStrings * FAdditionalInfo;
   AnsiString FLastDirectoryChange;
   TCurrentFSProtocol FFSProtocol;
+  TTerminal * FCommandSession;
   void __fastcall CommandError(Exception * E, const AnsiString Msg);
   int __fastcall CommandError(Exception * E, const AnsiString Msg, int Answers);
   AnsiString __fastcall PeekCurrentDirectory();
@@ -151,6 +152,8 @@ private:
   bool __fastcall GetAreCachesEmpty() const;
   void __fastcall ClearCachedFileList(const AnsiString Path, bool SubDirs);
   void __fastcall AddCachedFileList(TRemoteFileList * FileList);
+  bool __fastcall GetCommandSessionOpened();
+  TTerminal * __fastcall GetCommandSession();
 
 protected:
   bool FReadCurrentDirectoryPending;
@@ -298,6 +301,26 @@ public:
   __property bool IsCapable[TFSCapability Capability] = { read = GetIsCapable };
   __property TStrings * AdditionalInfo = { read = GetAdditionalInfo };
   __property bool AreCachesEmpty = { read = GetAreCachesEmpty };
+  __property bool CommandSessionOpened = { read = GetCommandSessionOpened };
+  __property TTerminal * CommandSession = { read = GetCommandSession };
+};
+//---------------------------------------------------------------------------
+class TSecondaryTerminal : public TTerminal
+{
+public:
+  __fastcall TSecondaryTerminal(TTerminal * MainTerminal);
+
+protected:
+  virtual void __fastcall DirectoryLoaded(TRemoteFileList * FileList);
+  virtual void __fastcall DirectoryModified(const AnsiString Path,
+    bool SubDirs);
+  virtual bool __fastcall DoPromptUser(AnsiString Prompt, TPromptKind Kind,
+    AnsiString & Response);
+  virtual void __fastcall SetSessionData(TSessionData * value);
+
+private:
+  bool FMasterPasswordTried;
+  TTerminal * FMainTerminal;
 };
 //---------------------------------------------------------------------------
 class TTerminalList : public TObjectList

+ 221 - 181
forms/CustomScpExplorer.cpp

@@ -2,8 +2,6 @@
 #include <vcl.h>
 #pragma hdrstop
 
-#include <DiscMon.hpp>
-
 #include <Common.h>
 
 #include "CustomScpExplorer.h"
@@ -28,6 +26,7 @@
 #include "Tools.h"
 #include "WinConfiguration.h"
 #include "TerminalManager.h"
+#include "EditorManager.h"
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma link "CustomDirView"
@@ -129,6 +128,9 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   FDDFileList = NULL;
   FPendingTempSpaceWarn = false;
 
+  FEditorManager = new TEditorManager();
+  FEditorManager->OnFileChange = ExecutedFileChanged;
+
   FQueueStatus = NULL;
   FQueueStatusSection = new TCriticalSection();
   FQueueStatusInvalidated = false;
@@ -167,6 +169,8 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
 //---------------------------------------------------------------------------
 __fastcall TCustomScpExplorerForm::~TCustomScpExplorerForm()
 {
+  delete FEditorManager;
+
   if (FDelayedDeletionTimer)
   {
     DoDelayedDeletion(NULL);
@@ -825,19 +829,22 @@ void __fastcall TCustomScpExplorerForm::ExecuteFileOperation(TFileOperation Oper
       assert(Param);
       assert(Side == osRemote);
 
-      FCustomCommandName = *((AnsiString *)Param);
-      try
+      if (EnsureAnyCommandCapability())
       {
-        AnsiString Command = TCustomFileSystem::CompleteCustomCommand(
-          WinConfiguration->CustomCommands->Values[FCustomCommandName],
-          "", CustomCommandGetParamValue);
-        Terminal->CustomCommandOnFiles(Command,
-          WinConfiguration->CustomCommands->Params[FCustomCommandName],
-          FileList);
-      }
-      __finally
-      {
-        FCustomCommandName = "";
+        FCustomCommandName = *((AnsiString *)Param);
+        try
+        {
+          AnsiString Command = TCustomFileSystem::CompleteCustomCommand(
+            WinConfiguration->CustomCommands->Values[FCustomCommandName],
+            "", CustomCommandGetParamValue);
+          Terminal->CustomCommandOnFiles(Command,
+            WinConfiguration->CustomCommands->Params[FCustomCommandName],
+            FileList);
+        }
+        __finally
+        {
+          FCustomCommandName = "";
+        }
       }
     }
     else if (Operation == foRemoteMove)
@@ -957,14 +964,19 @@ void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
 {
   assert(!WinConfiguration->DisableOpenEdit);
 
+  if (!FEditorManager->CanAddFile())
+  {
+    throw Exception(LoadStr(TOO_MANY_EDITORS));
+  }
+
   Side = GetSide(Side);
 
   bool Edit = (ExecuteFileBy == efEditor || ExecuteFileBy == efAlternativeEditor);
   bool InternalEdit = Edit &&
     ((WinConfiguration->Editor.Editor == edInternal) !=
      (ExecuteFileBy == efAlternativeEditor));
-  FExecutedFileForceText =
-    (InternalEdit || (Edit && WinConfiguration->Editor.ExternalEditorText));
+  AnsiString FileName;
+  bool ForceText = (InternalEdit || (Edit && WinConfiguration->Editor.ExternalEditorText));
 
   TStrings * FileList = DirView(Side)->CreateFocusedFileList(Side == osLocal);
   try
@@ -973,7 +985,7 @@ void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
     if (Side == osRemote)
     {
       TCopyParamType CopyParam = GUIConfiguration->CopyParam;
-      if (FExecutedFileForceText)
+      if (ForceText)
       {
         CopyParam.TransferMode = tmAscii;
       }
@@ -982,7 +994,10 @@ void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
       CopyParam.ResumeSupport = rsOff;
 
       AnsiString TempDir = WinConfiguration->TemporaryTranferDir();
-      ForceDirectories(TempDir);
+      if (!ForceDirectories(TempDir))
+      {
+        throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (TempDir)));
+      }
 
       FAutoOperation = true;
       Terminal->ExceptionOnFail = true;
@@ -996,11 +1011,11 @@ void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
         Terminal->ExceptionOnFail = false;
       }
 
-      FExecutedFile = TempDir + FileList->Strings[0];
+      FileName = TempDir + FileList->Strings[0];
     }
     else
     {
-      FExecutedFile = FileList->Strings[0];
+      FileName = FileList->Strings[0];
     }
   }
   __finally
@@ -1008,210 +1023,155 @@ void __fastcall TCustomScpExplorerForm::ExecuteFile(TOperationSide Side,
     delete FileList;
   }
 
-  Terminal->BeginTransaction();
+  TEditedFileData Data;
+  if (Side == osRemote)
+  {
+    Data.Terminal = Terminal;
+    Data.Queue = Queue;
+    Data.ForceText = ForceText;
+    Data.RemoteDirectory = RemoteDirView->PathName;
+    Data.SessionName = Terminal->SessionData->SessionName;
+  }
+
+  bool SingleEditor = WinConfiguration->Editor.SingleEditor;
+  TOperationStatusForm * StatusForm = NULL;
   try
   {
-    try
+    bool CloseFlag = false;
+    bool * PCloseFlag = NULL;
+
+    if ((Side == osRemote) && SingleEditor)
     {
-      FExecutedFileTimestamp = FileAge(FExecutedFile);
-      FFileExecutedBy = ExecuteFileBy;
+      StatusForm = new TOperationStatusForm(Application);
+      StatusForm->Status = LoadStr(DOCUMENT_WAIT);
+      StatusForm->ShowAsModal();
+      PCloseFlag = &CloseFlag;
+    }
 
-      if (InternalEdit)
+    if (InternalEdit)
+    {
+      if (Side == osRemote)
       {
-        TNotifyEvent OnFileChanged = NULL;
-        AnsiString Caption = FExecutedFile;
-        if (Side == osRemote)
-        {
-          OnFileChanged = ExecutedFileChanged;
-          Caption = RemoteDirView->Path + ExtractFileName(FExecutedFile);
-        }
-        DoEditorForm(FExecutedFile, this, OnFileChanged, Caption);
+        AnsiString Caption = RemoteDirView->Path + ExtractFileName(FileName);
+        TForm * Editor = ShowEditorForm(FileName, this, FEditorManager->FileChanged,
+          FEditorManager->FileClosed, Caption, !SingleEditor);
+
+        FEditorManager->AddFileInternal(FileName, Data, PCloseFlag, Editor);
       }
       else
       {
-        TDiscMonitor * DiscMonitor = NULL;
-        try
-        {
-          if (Side == osRemote)
-          {
-            DiscMonitor = new TDiscMonitor(this);
-            DiscMonitor->SubTree = false;
-            DiscMonitor->Filters = TMonitorFilters() << moLastWrite;
-            DiscMonitor->AddDirectory(ExtractFilePath(FExecutedFile), false);
-            DiscMonitor->OnChange = ExecutedFileChangedNotification;
-            DiscMonitor->Active = true;
-          }
-
-          TOperationStatusForm * StatusForm = new TOperationStatusForm(Application);
-          try
-          {
-            StatusForm->Status = LoadStr(DOCUMENT_WAIT);
-            StatusForm->ShowAsModal();
-
-            if (Edit)
-            {
-              AnsiString ExternalEditor, Program, Params, Dir;
-              ExternalEditor = WinConfiguration->Editor.ExternalEditor;
-              TWinConfiguration::ReformatFileNameCommand(ExternalEditor);
-              SplitCommand(ExternalEditor, Program, Params, Dir);
-              assert(Params.Pos(ShellCommandFileNamePattern) > 0);
-              Params = StringReplace(Params, ShellCommandFileNamePattern,
-                AddPathQuotes(FExecutedFile), TReplaceFlags() << rfReplaceAll);
-              if (ExecuteShellAndWait(Program, Params) < 0)
-              {
-                throw Exception(FMTLOAD(EDITOR_ERROR, (Program)));
-              }
-            }
-            else
-            {
-              assert(Side == osRemote);
-              if (ExecuteShellAndWait(FExecutedFile, "") < 0)
-              {
-                throw Exception(FMTLOAD(EXECUTE_FILE_ERROR, (FExecutedFile)));
-              }
-            }
-          }
-          __finally
-          {
-            delete StatusForm;
-          }
-
-          if (Side == osRemote)
-          {
-            if (DiscMonitor)
-            {
-              DiscMonitor->Active = false;
-            }
-            // upload file if it was saved while [editor] was closed
-            ExecutedFileChanged(NULL);
-          }
-        }
-        __finally
-        {
-          delete DiscMonitor;
-        }
+        ShowEditorForm(FileName, this, NULL, NULL, "", true);
       }
     }
-    __finally
+    else
     {
-      AnsiString FileName = FExecutedFile;
-      FExecutedFile = "";
-      if (Side == osRemote)
-      {
-        bool Deleted;
-        AnsiString DirName = ExtractFilePath(FileName);
+      HANDLE Process;
 
-        if (WinConfiguration->ForceDeleteTempFolder)
+      if (Edit)
+      {
+        AnsiString ExternalEditor, Program, Params, Dir;
+        ExternalEditor = WinConfiguration->Editor.ExternalEditor;
+        TWinConfiguration::ReformatFileNameCommand(ExternalEditor);
+        SplitCommand(ExternalEditor, Program, Params, Dir);
+        assert(Params.Pos(ShellCommandFileNamePattern) > 0);
+        Params = StringReplace(Params, ShellCommandFileNamePattern,
+          AddPathQuotes(FileName), TReplaceFlags() << rfReplaceAll);
+        if (!ExecuteShell(Program, Params, Process))
         {
-          Deleted = RecursiveDeleteFile(ExcludeTrailingBackslash(DirName), false);
+          throw Exception(FMTLOAD(EDITOR_ERROR, (Program)));
         }
-        else
+      }
+      else
+      {
+        assert(Side == osRemote);
+        if (!ExecuteShell(FileName, "", Process))
         {
-          Deleted = DeleteFile(FileName) && RemoveDir(DirName);
+          throw Exception(FMTLOAD(EXECUTE_FILE_ERROR, (FileName)));
         }
+      }
 
-        if (!Deleted)
-        {
-          throw Exception(FMTLOAD(DELETE_TEMP_EXECUTE_FILE_ERROR, (DirName)));
-        }
+      if (Side == osRemote)
+      {
+        FEditorManager->AddFileExternal(FileName, Data, PCloseFlag, Process);
       }
-      else
+    }
+
+    if (StatusForm != NULL)
+    {
+      do
       {
-        ReloadLocalDirectory();
+        Application->ProcessMessages();
       }
+      while (!Application->Terminated && !CloseFlag);
     }
   }
   __finally
   {
-    Terminal->EndTransaction();
+    if (StatusForm != NULL)
+    {
+      delete StatusForm;
+    }
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::ExecutedFileChanged(TObject * Sender)
+void __fastcall TCustomScpExplorerForm::ExecutedFileChanged(const AnsiString FileName,
+  const TEditedFileData & Data, HANDLE UploadCompleteEvent)
 {
-  static Uploading = 0;
+  if (!TTerminalManager::Instance()->IsValidTerminal(Data.Terminal) ||
+      !Data.Terminal->Active)
+  {
+    throw Exception(FMTLOAD(EDIT_SESSION_CLOSED,
+      (ExtractFileName(FileName), Data.SessionName)));
+  }
+
+  TStrings * FileList = new TStringList();
   try
   {
-    assert(!FExecutedFile.IsEmpty());
+    FileList->Add(FileName);
 
-    if (Uploading == 1)
+    TGUICopyParamType CopyParam = GUIConfiguration->CopyParam;
+    if (Data.ForceText)
     {
-      Uploading = 2;
+      CopyParam.TransferMode = tmAscii;
     }
-    else
+    CopyParam.FileNameCase = ncNoChange;
+    CopyParam.PreserveRights = false;
+    CopyParam.ResumeSupport = rsOff;
+
+    if (WinConfiguration->Editor.SingleEditor)
     {
-      Uploading = 1;
+      FAutoOperation = true;
+      Data.Terminal->ExceptionOnFail = true;
       try
       {
-        int FileTimestamp = FileAge(FExecutedFile);
-        if (FileTimestamp != FExecutedFileTimestamp)
-        {
-          FExecutedFileTimestamp = FileTimestamp;
-
-          TStrings * FileList = new TStringList();
-          try
-          {
-            FileList->Add(FExecutedFile);
-
-            TCopyParamType CopyParam = GUIConfiguration->CopyParam;
-            if (FExecutedFileForceText)
-            {
-              CopyParam.TransferMode = tmAscii;
-            }
-            CopyParam.FileNameCase = ncNoChange;
-            CopyParam.PreserveRights = false;
-            CopyParam.ResumeSupport = rsOff;
-
-            FAutoOperation = true;
-            Terminal->ExceptionOnFail = true;
-            try
-            {
-              Terminal->CopyToRemote(FileList, RemoteDirView->PathName,
-                &CopyParam, cpNoConfirmation);
-            }
-            __finally
-            {
-              FAutoOperation = false;
-              Terminal->ExceptionOnFail = false;
-            }
-          }
-          __finally
-          {
-            delete FileList;
-          }
-        }
+        Data.Terminal->CopyToRemote(FileList, RemoteDirView->PathName,
+          &CopyParam, cpNoConfirmation);
       }
       __finally
       {
-        if (Uploading == 2)
-        {
-          Uploading = 0;
-          ExecutedFileChanged(this);
-        }
-        else
+        FAutoOperation = false;
+        Data.Terminal->ExceptionOnFail = false;
+        if (UploadCompleteEvent != INVALID_HANDLE_VALUE)
         {
-          Uploading = 0;
+          SetEvent(UploadCompleteEvent);
         }
       }
     }
-  }
-  catch (Exception & E)
-  {
-    if (dynamic_cast<TDiscMonitor *> (Sender))
-    {
-      Terminal->DoHandleExtendedException(&E);
-    }
     else
     {
-      throw;
+      assert(Queue != NULL);
+
+      int Params = FLAGMASK(CopyParam.QueueNoConfirmation, cpNoConfirmation);
+      TQueueItem * QueueItem = new TUploadQueueItem(Data.Terminal, FileList,
+        Data.RemoteDirectory, &CopyParam, Params);
+      QueueItem->CompleteEvent = UploadCompleteEvent;
+      Data.Queue->AddItem(QueueItem);
     }
   }
-}
-//---------------------------------------------------------------------------
-void __fastcall TCustomScpExplorerForm::ExecutedFileChangedNotification(
-  TObject * Sender, const AnsiString /*Directory*/)
-{
-  ExecutedFileChanged(Sender);
+  __finally
+  {
+    delete FileList;
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::RemoteDirViewEnter(TObject * /*Sender*/)
@@ -1466,6 +1426,8 @@ void __fastcall TCustomScpExplorerForm::SessionStatusBarDrawPanel(
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::Idle(bool AppIdle)
 {
+  FEditorManager->Check();
+
   // terminal may not be active here, when connection is closed by remote side
   // and coresponding error message is being displayed
   if (Terminal && Terminal->Active)
@@ -1696,6 +1658,20 @@ void __fastcall TCustomScpExplorerForm::FormCloseQuery(TObject * /*Sender*/,
   {
     CanClose = CanCloseQueue();
   }
+
+  if (CanClose)
+  {
+    CanClose = FEditorManager->CloseInternalEditors(CloseInternalEditor) &&
+      (FEditorManager->Empty(true) ||
+       (MessageDialog(LoadStr(PENDING_EDITORS), qtWarning, qaIgnore | qaCancel) == qaIgnore));
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::CloseInternalEditor(TObject * Sender)
+{
+  TForm * Form = dynamic_cast<TForm *>(Sender);
+  assert(Form != NULL);
+  Form->Close();
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::DropDownButtonMenu(TObject *Sender)
@@ -1873,7 +1849,7 @@ bool __fastcall TCustomScpExplorerForm::DoSynchronizeDirectories(
   Params.Params = GUIConfiguration->SynchronizeParams;
   Params.Recurse = GUIConfiguration->SynchronizeRecurse;
   bool SaveSettings = false;
-  TSynchronizeController Controller(&DoSynchronize);
+  TSynchronizeController Controller(&DoSynchronize, &DoSynchronizeInvalid);
   bool Result = DoSynchronizeDialog(Params, Controller.StartStop, SaveSettings);
   if (Result)
   {
@@ -1908,6 +1884,19 @@ void __fastcall TCustomScpExplorerForm::DoSynchronize(
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::DoSynchronizeInvalid(
+  TSynchronizeController * /*Sender*/, const AnsiString Directory)
+{
+  if (!Directory.IsEmpty())
+  {
+    SimpleErrorDialog(FMTLOAD(WATCH_ERROR_DIRECTORY, (Directory)));
+  }
+  else
+  {
+    SimpleErrorDialog(LoadStr(WATCH_ERROR_GENERAL));
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::FullSynchronizeDirectories()
 {
   assert(false);
@@ -2139,9 +2128,57 @@ void __fastcall TCustomScpExplorerForm::OpenInPutty()
   OpenSessionInPutty(Terminal->SessionData);
 }
 //---------------------------------------------------------------------------
+bool __fastcall TCustomScpExplorerForm::EnsureAnyCommandCapability()
+{
+  bool Result = FTerminal->IsCapable[fcAnyCommand] ||
+    FTerminal->CommandSessionOpened;
+
+  if (!Result)
+  {
+    if (!GUIConfiguration->ConfirmCommandSession)
+    {
+      Result = true;
+    }
+    else
+    {
+      TMessageParams Params(mpNeverAskAgainCheck);
+      int Answer = MessageDialog(FMTLOAD(OPEN_COMMAND_SESSION,
+        (Terminal->ProtocolName, Terminal->ProtocolName)), qtConfirmation,
+        qaOK | qaCancel, 0, &Params);
+      if (Answer == qaNeverAskAgain)
+      {
+        GUIConfiguration->ConfirmCommandSession = false;
+        Result = true;
+      }
+      else if (Answer == qaOK)
+      {
+        Result = true;
+      }
+    }
+
+    if (Result)
+    {
+      try
+      {
+        TTerminalManager::ConnectTerminal(FTerminal->CommandSession);
+      }
+      catch(Exception & E)
+      {
+        ShowExtendedExceptionEx(FTerminal->CommandSession, &E);
+        Result = false;
+      }
+    }
+  }
+
+  return Result;
+}
+//---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::OpenConsole(AnsiString Command)
 {
-  DoConsoleDialog(Terminal, Command);
+  if (EnsureAnyCommandCapability())
+  {
+    DoConsoleDialog(Terminal, Command);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::FileControlDDDragEnter(
@@ -2404,7 +2441,10 @@ void __fastcall TCustomScpExplorerForm::DDExtInitDrag(TFileList * FileList,
 {
   FDragExtFakeDirectory =
     ExcludeTrailingBackslash(WinConfiguration->TemporaryTranferDir());
-  ForceDirectories(FDragExtFakeDirectory);
+  if (!ForceDirectories(FDragExtFakeDirectory))
+  {
+    throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (FDragExtFakeDirectory)));
+  }
   FileList->AddItem(NULL, FDragExtFakeDirectory);
 
   Created = true;
@@ -2677,7 +2717,7 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDTargetDrop()
       }
       else
       {
-        throw Exception(FMTLOAD(DD_DIR_EXCEPTION, (TargetDir)));
+        throw Exception(FMTLOAD(CREATE_TEMP_DIR_ERROR, (TargetDir)));
       }
     }
   }

+ 9 - 6
forms/CustomScpExplorer.h

@@ -30,6 +30,8 @@ class TQueueItem;
 class TQueueItemProxy;
 class TQueueController;
 class TSynchronizeController;
+class TEditorManager;
+struct TEditedFileData;
 //---------------------------------------------------------------------------
 enum TActionAllowed { aaShortCut, aaUpdate, aaExecute };
 enum TActionFlag { afLocal = 1, afRemote = 2, afExplorer = 4 , afCommander = 8 };
@@ -127,10 +129,6 @@ private:
   bool FQueueItemInvalidated;
   bool FFormRestored;
   bool FAutoOperation;
-  bool FExecutedFileForceText;
-  AnsiString FExecutedFile;
-  int FExecutedFileTimestamp;
-  TExecuteFileBy FFileExecutedBy;
   bool FForceExecution;
   bool FShowStatusBarHint;
   AnsiString FStatusBarHint;
@@ -152,6 +150,7 @@ private:
   TQueueController * FQueueController;
   int FLastDropEffect;
   bool FPendingTempSpaceWarn;
+  TEditorManager * FEditorManager;
 
   bool __fastcall GetEnableFocusedOperation(TOperationSide Side);
   bool __fastcall GetEnableSelectedOperation(TOperationSide Side);
@@ -163,6 +162,7 @@ private:
   void __fastcall SessionComboChange(TObject * Sender);
   void __fastcall CustomCommandGetParamValue(const AnsiString Name,
     AnsiString & Value);
+  void __fastcall CloseInternalEditor(TObject * Sender);
 
 protected:
   TOperationSide FCurrentSide;
@@ -204,8 +204,8 @@ protected:
   virtual void __fastcall FileOperationProgress(
     TFileOperationProgressType & ProgressData, TCancelStatus & Cancel);
   void __fastcall OperationComplete(const TDateTime & StartTime);
-  void __fastcall ExecutedFileChangedNotification(TObject * Sender, const AnsiString Directory);
-  void __fastcall ExecutedFileChanged(TObject * Sender);
+  void __fastcall ExecutedFileChanged(const AnsiString FileName,
+    const TEditedFileData & Data, HANDLE UploadCompleteEvent);
   void __fastcall CMAppSysCommand(TMessage & Message);
   DYNAMIC void __fastcall DoShow();
   TStrings * __fastcall CreateVisitedDirectories(TOperationSide Side);
@@ -219,6 +219,8 @@ protected:
   void __fastcall DoSynchronize(TSynchronizeController * Sender,
     const AnsiString LocalDirectory, const AnsiString RemoteDirectory,
     const TSynchronizeParamType & Params);
+  void __fastcall DoSynchronizeInvalid(TSynchronizeController * Sender,
+    const AnsiString Directory);
   void __fastcall Synchronize(const AnsiString LocalDirectory,
     const AnsiString RemoteDirectory, TSynchronizeMode Mode,
     const TCopyParamType & CopyParam, int Params);
@@ -255,6 +257,7 @@ protected:
   void __fastcall RemoteFileControlDDTargetDrop();
   void __fastcall RemoteFileControlFileOperation(TObject * Sender,
     TFileOperation Operation, bool NoConfirmation, void * Param);
+  bool __fastcall EnsureAnyCommandCapability();
 
   #pragma warn -inl
   BEGIN_MESSAGE_MAP

+ 47 - 11
forms/Editor.cpp

@@ -14,22 +14,28 @@
 #pragma package(smart_init)
 #pragma resource "*.dfm"
 //---------------------------------------------------------------------------
-void __fastcall DoEditorForm(const AnsiString FileName, TCustomForm * ParentForm,
-  TNotifyEvent OnFileChanged, const AnsiString Caption)
+TForm * __fastcall ShowEditorForm(const AnsiString FileName, TCustomForm * ParentForm,
+  TNotifyEvent OnFileChanged, TNotifyEvent OnClose, const AnsiString Caption,
+  bool ShowWindowButton)
 {
   TEditorForm * Dialog = new TEditorForm(Application);
   try
   {
+    Dialog->ShowWindowButton = ShowWindowButton;
     Dialog->FileName = FileName;
     Dialog->ParentForm = ParentForm;
     Dialog->Caption = Caption.IsEmpty() ? FileName : Caption;
     Dialog->OnFileChanged = OnFileChanged;
-    Dialog->Execute();
+    Dialog->OnWindowClose = OnClose;
+    Dialog->Show();
   }
-  __finally
+  catch(...)
   {
     delete Dialog;
+    throw;
   }
+
+  return Dialog;
 }
 //---------------------------------------------------------------------------
 __fastcall TEditorForm::TEditorForm(TComponent* Owner)
@@ -39,6 +45,7 @@ __fastcall TEditorForm::TEditorForm(TComponent* Owner)
   FCaretPos.x = -1;
   FCaretPos.y = -1;
   FLastFindDialog = NULL;
+  FShowWindowButton = false;
   ApplyConfiguration();
   FindDialog->FindText = WinConfiguration->Editor.FindText;
   TFindOptions Options = FindDialog->Options;
@@ -68,12 +75,6 @@ __fastcall TEditorForm::~TEditorForm()
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall TEditorForm::Execute()
-{
-  ShowModal();
-  return true;
-}
-//---------------------------------------------------------------------------
 void __fastcall TEditorForm::SetFileName(const AnsiString value)
 {
   if (value != FFileName)
@@ -256,6 +257,7 @@ void __fastcall TEditorForm::UpdateControls()
   }
   StatusBar->Panels->Items[3]->Text =
     (EditorMemo->Modified ? LoadStr(EDITOR_MODIFIED) : AnsiString(""));
+  EditorActions->UpdateAction(SaveAction);  
 }
 //---------------------------------------------------------------------------
 void __fastcall TEditorForm::EditorMemoMouseUp(TObject * /*Sender*/,
@@ -446,6 +448,40 @@ void __fastcall TEditorForm::GoToLine()
   }
 }
 //---------------------------------------------------------------------------
+void __fastcall TEditorForm::FormClose(TObject * Sender,
+  TCloseAction & Action)
+{
+  if (FOnWindowClose != NULL)
+  {
+    try
+    {
+      FOnWindowClose(Sender);
+    }
+    catch(Exception & E)
+    {
+      ShowExtendedException(&E);
+    }
+  }
 
-
+  Action = caFree;
+}
+//---------------------------------------------------------------------------
+void __fastcall TEditorForm::SetShowWindowButton(bool value)
+{
+  if (value != ShowWindowButton)
+  {
+    FShowWindowButton = value;
+    RecreateWnd();
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TEditorForm::CreateParams(TCreateParams & Params)
+{
+  TForm::CreateParams(Params);
+  if (ShowWindowButton)
+  {
+    Params.WndParent = GetDesktopWindow();
+  }
+}
+//---------------------------------------------------------------------------
 

+ 2 - 1
forms/Editor.dfm

@@ -23,7 +23,8 @@ object EditorForm: TEditorForm
     000000070000000700000003000000030000000100000021000000730000}
   KeyPreview = True
   OldCreateOrder = False
-  Position = poDefault
+  Position = poDefaultPosOnly
+  OnClose = FormClose
   OnCloseQuery = FormCloseQuery
   OnShow = FormShow
   PixelsPerInch = 96

+ 7 - 1
forms/Editor.h

@@ -81,21 +81,26 @@ __published:
   void __fastcall EditorMemoChange(TObject *Sender);
   void __fastcall FindDialogFind(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
+  void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
 private:
   AnsiString FFileName;
   TNotifyEvent FOnFileChanged;
+  TNotifyEvent FOnWindowClose;
   TCustomForm * FParentForm;
   TFindDialog * FLastFindDialog;
   TPoint FCaretPos;
+  bool FShowWindowButton;
   void __fastcall SetFileName(const AnsiString value);
   void __fastcall SetParentForm(TCustomForm * value);
+  void __fastcall SetShowWindowButton(bool value);
 public:
   __fastcall TEditorForm(TComponent* Owner);
   virtual __fastcall ~TEditorForm();
-  bool __fastcall Execute();
   __property AnsiString FileName = { read = FFileName, write = SetFileName };
   __property TNotifyEvent OnFileChanged = { read = FOnFileChanged, write = FOnFileChanged };
+  __property TNotifyEvent OnWindowClose = { read = FOnWindowClose, write = FOnWindowClose };
   __property TCustomForm * ParentForm = { read = FParentForm, write = SetParentForm };
+  __property bool ShowWindowButton = { read = FShowWindowButton, write = SetShowWindowButton };
 protected:
   void __fastcall ApplyConfiguration();
   bool __fastcall CursorInUpperPart();
@@ -105,6 +110,7 @@ protected:
   void __fastcall PositionFindDialog(bool VerticalOnly);
   void __fastcall StartFind(bool Find);
   void __fastcall UpdateControls();
+  virtual void __fastcall CreateParams(TCreateParams & Params);
 };
 //---------------------------------------------------------------------------
 #endif

+ 2 - 0
forms/FileSystemInfo.cpp

@@ -4,6 +4,7 @@
 
 #include <Common.h>
 #include <Terminal.h>
+#include <VCLCommon.h>
 #include "FileSystemInfo.h"
 //---------------------------------------------------------------------
 #pragma link "XPGroupBox"
@@ -26,6 +27,7 @@ void __fastcall DoFileSystemInfoDialog(TTerminal * Terminal)
 __fastcall TFileSystemInfoDialog::TFileSystemInfoDialog(TComponent* AOwner)
 	: TForm(AOwner)
 {
+  UseSystemSettings(this);
 }
 //---------------------------------------------------------------------
 AnsiString __fastcall TFileSystemInfoDialog::CapabilityStr(TFSCapability Capability)

+ 8 - 8
forms/Login.dfm

@@ -1364,7 +1364,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 0
           end
           object BugPlainPW1Combo: TComboBox
@@ -1374,7 +1374,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 1
           end
           object BugRSA1Combo: TComboBox
@@ -1384,7 +1384,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 2
           end
           object BugHMAC2Combo: TComboBox
@@ -1394,7 +1394,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 3
           end
           object BugDeriveKey2Combo: TComboBox
@@ -1404,7 +1404,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 4
           end
           object BugRSAPad2Combo: TComboBox
@@ -1414,7 +1414,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 5
           end
           object BugDHGEx2Combo: TComboBox
@@ -1424,7 +1424,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 6
           end
           object BugPKSessID2Combo: TComboBox
@@ -1434,7 +1434,7 @@ object LoginDialog: TLoginDialog
             Height = 21
             Style = csDropDownList
             Anchors = [akLeft, akTop, akRight]
-            ItemHeight = 13
+            ItemHeight = 0
             TabOrder = 7
           end
         end

+ 14 - 0
forms/MessageDlg.cpp

@@ -24,6 +24,7 @@ protected:
 
   DYNAMIC void __fastcall KeyDown(Word & Key, TShiftState Shift);
   AnsiString __fastcall GetFormText();
+  virtual void __fastcall CreateParams(TCreateParams & Params);
 
 private:
   TLabel * Message;
@@ -84,6 +85,16 @@ AnsiString __fastcall TMessageForm::GetFormText()
   return Result;
 }
 //---------------------------------------------------------------------------
+void __fastcall TMessageForm::CreateParams(TCreateParams & Params)
+{
+  TForm::CreateParams(Params);
+  if ((Screen != NULL) && (Screen->ActiveForm != NULL) &&
+      Screen->ActiveForm->HandleAllocated())
+  {
+    Params.WndParent = Screen->ActiveForm->Handle;
+  }
+}
+//---------------------------------------------------------------------------
 const ResourceString * Captions[] = { &_SMsgDlgWarning, &_SMsgDlgError, &_SMsgDlgInformation,
   &_SMsgDlgConfirm, NULL };
 const char * IconIDs[] = { IDI_EXCLAMATION, IDI_HAND, IDI_ASTERISK,
@@ -256,6 +267,7 @@ TForm * __fastcall TMessageForm::Create(const AnsiString & Msg,
     TMoreButton * MoreButton = new TMoreButton(Result);
     MoreButton->Parent = Result;
     MoreButton->Panel = MessageMemo;
+    MoreButton->RepositionForm = true;
     MoreButton->Name = "MoreButton";
 
     MessageMemo->TabOrder = static_cast<short>(MoreButton->TabOrder + 1);
@@ -335,6 +347,8 @@ TForm * __fastcall TMessageForm::Create(const AnsiString & Msg,
     X += ButtonWidth + ButtonSpacing;
   }
 
+  UseSystemSettings(Result);
+
   return Result;
 }
 //---------------------------------------------------------------------------

+ 3 - 5
forms/NonVisual.cpp

@@ -156,8 +156,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(CurrentDeleteAction, EnableSelectedOperation)
   UPD(CurrentPropertiesAction, EnableSelectedOperation)
   UPD(RemoteMoveToAction, EnableSelectedOperation && (DirView(osRemote) == DirView(osCurrent)))
-  UPD(FileListToCommandLineAction, EnableSelectedOperation &&
-    ((DirView(osLocal) == DirView(osCurrent)) || ScpExplorer->Terminal->IsCapable[fcAnyCommand]))
+  UPD(FileListToCommandLineAction, EnableSelectedOperation)
   UPD(FileListToClipboardAction, EnableSelectedOperation)
   UPD(FullFileListToClipboardAction, EnableSelectedOperation)
   // directory
@@ -313,7 +312,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
   UPD(CompareDirectoriesAction, true)
   UPD(SynchronizeAction, true)
   UPD(FullSynchronizeAction, true)
-  UPD(ConsoleAction, ScpExplorer->Terminal && ScpExplorer->Terminal->IsCapable[fcAnyCommand])
+  UPD(ConsoleAction, true)
   UPD(PuttyAction, true)
   UPD(SynchronizeBrowsingAction, true)
   UPD(CloseApplicationAction, true)
@@ -322,8 +321,7 @@ void __fastcall TNonVisualDataModule::ExplorerActionsUpdate(
 
   // CUSTOM COMMANDS
   UPD(CustomCommandsAction,
-    (ScpExplorer->DirView(osCurrent) == ScpExplorer->DirView(osRemote)) &&
-    ScpExplorer->Terminal && ScpExplorer->Terminal->IsCapable[fcAnyCommand])
+    (ScpExplorer->DirView(osCurrent) == ScpExplorer->DirView(osRemote)))
   UPD(CustomCommandsCustomizeAction, true)
 
   // QUEUE

+ 6 - 0
forms/NonVisual.dfm

@@ -8966,6 +8966,9 @@ object NonVisualDataModule: TNonVisualDataModule
     object CopyPathtoClipboard1: TMenuItem
       Action = RemotePathToClipboardAction
     end
+    object OpenDirectoryBookmark1: TMenuItem
+      Action = RemoteOpenDirAction
+    end
     object N51: TMenuItem
       Caption = '-'
       Hint = 'E'
@@ -8998,6 +9001,9 @@ object NonVisualDataModule: TNonVisualDataModule
     object CopyPathtoClipboard2: TMenuItem
       Action = LocalPathToClipboardAction
     end
+    object OpenDirectoryBookmark2: TMenuItem
+      Action = LocalOpenDirAction
+    end
     object N52: TMenuItem
       Caption = '-'
       Hint = 'E'

+ 0 - 41
forms/NonVisual.dti

@@ -1,41 +0,0 @@
-[Designer]
-Version=1
-Left=279
-Top=108
-Width=741
-Height=547
-Splitter=185
-SelectedTab=Components
-
-[Components]
-Version=1
-Left=0
-Top=0
-
-[TreeView]
-Version=1
-PrintHeader=1
-PrintToSingle=1
-PrintToFile=0
-PrintBorders=1
-PrintSelected=0
-PrintVisible=0
-ExpandedItems=NonVisualDataModule\ExplorerMenu,NonVisualDataModule\ExplorerActions
-
-[DataDiagrams]
-Version=1
-PrintHeader=1
-PrintToSingle=1
-PrintToFile=0
-PrintBorders=1
-Left=0
-Top=0
-ModeSelected=SelectionMode
-Count=1
-
-[DataDiagrams.Diagram.0]
-Islands=
-Comments=
-Bridges=
-Alludes=
-

+ 2 - 0
forms/NonVisual.h

@@ -643,6 +643,8 @@ __published:	// IDE-managed Components
   TMenuItem *N78;
   TMenuItem *Tree8;
   TAction *GoToTreeAction;
+  TMenuItem *OpenDirectoryBookmark1;
+  TMenuItem *OpenDirectoryBookmark2;
   void __fastcall LogActionsUpdate(TBasicAction *Action, bool &Handled);
   void __fastcall LogActionsExecute(TBasicAction *Action, bool &Handled);
   void __fastcall ExplorerActionsUpdate(TBasicAction *Action, bool &Handled);

+ 7 - 0
forms/Preferences.cpp

@@ -136,6 +136,7 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
   BOOLPROP(ConfirmClosingSession);
   BOOLPROP(ConfirmExitOnCompletion);
   BOOLPROP(UseLocationProfiles);
+  BOOLPROP(ConfirmCommandSession);
   BOOLPROP(ContinueOnError);
   BOOLPROP(DDAllowMoveInit);
   BOOLPROP(BeepOnFinish);
@@ -174,6 +175,9 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
   RandomSeedFileEdit->Text = Configuration->RandomSeedFile;
 
   // editor
+  EditorSingleEditorOnCheck->Checked = WinConfiguration->Editor.SingleEditor;
+  EditorSingleEditorOffCheck->Checked = !WinConfiguration->Editor.SingleEditor;
+
   EditorInternalButton->Checked = WinConfiguration->Editor.Editor == edInternal;
   EditorExternalButton->Checked = WinConfiguration->Editor.Editor == edExternal;
 
@@ -262,6 +266,7 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
     BOOLPROP(ConfirmClosingSession);
     BOOLPROP(ConfirmExitOnCompletion);
     BOOLPROP(UseLocationProfiles);
+    BOOLPROP(ConfirmCommandSession);
     BOOLPROP(ContinueOnError);
     BOOLPROP(DDAllowMoveInit);
     BOOLPROP(BeepOnFinish);
@@ -298,6 +303,8 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
     Configuration->RandomSeedFile = RandomSeedFileEdit->Text;
 
     // editor
+    WinConfiguration->Editor.SingleEditor = EditorSingleEditorOnCheck->Checked;
+
     WinConfiguration->Editor.Editor =
       (EditorInternalButton->Checked || ExternalEditorEdit->Text.IsEmpty()) ?
         edInternal : edExternal;

+ 131 - 61
forms/Preferences.dfm

@@ -71,13 +71,13 @@ object PreferencesDialog: TPreferencesDialog
           Left = 8
           Top = 8
           Width = 362
-          Height = 224
+          Height = 245
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Confirmations'
           TabOrder = 0
           DesignSize = (
             362
-            224)
+            245)
           object CopyOnDoubleClickCheck: TCheckBox
             Left = 16
             Top = 153
@@ -134,18 +134,18 @@ object PreferencesDialog: TPreferencesDialog
             Width = 338
             Height = 17
             Anchors = [akLeft, akTop, akRight]
-            Caption = '&Drag && drop operations'
+            Caption = 'D&rag && drop operations'
             TabOrder = 5
             OnClick = ControlChange
           end
           object ContinueOnErrorCheck: TCheckBox
             Left = 16
-            Top = 197
+            Top = 219
             Width = 330
             Height = 17
             Anchors = [akLeft, akTop, akRight]
             Caption = 'Continue on &error (advanced users)'
-            TabOrder = 8
+            TabOrder = 9
             OnClick = ControlChange
           end
           object ConfirmExitOnCompletionCheck: TCheckBox
@@ -154,7 +154,7 @@ object PreferencesDialog: TPreferencesDialog
             Width = 330
             Height = 17
             Anchors = [akLeft, akTop, akRight]
-            Caption = 'Exiting application on &operation completion'
+            Caption = 'Exiting application on o&peration completion'
             TabOrder = 4
             OnClick = ControlChange
           end
@@ -168,10 +168,20 @@ object PreferencesDialog: TPreferencesDialog
             TabOrder = 2
             OnClick = ControlChange
           end
+          object ConfirmCommandSessionCheck: TCheckBox
+            Left = 16
+            Top = 197
+            Width = 330
+            Height = 17
+            Anchors = [akLeft, akTop, akRight]
+            Caption = 'Opening separate &shell session'
+            TabOrder = 8
+            OnClick = ControlChange
+          end
         end
         object NotificationsGroup: TXPGroupBox
           Left = 8
-          Top = 238
+          Top = 256
           Width = 362
           Height = 51
           Anchors = [akLeft, akTop, akRight]
@@ -513,16 +523,19 @@ object PreferencesDialog: TPreferencesDialog
           Height = 345
           TabOrder = 0
           inherited CommonPropertiesGroup: TXPGroupBox
-            Left = 198
+            Left = 197
             Top = 209
             Height = 73
             Caption = 'Common options'
+            DesignSize = (
+              173
+              73)
             inherited CommonPreserveTimestampCheck: TCheckBox
               Top = 19
             end
           end
           inherited LocalPropertiesGroup: TXPGroupBox
-            Left = 198
+            Left = 197
             Top = 156
             Height = 48
             Caption = 'Download options'
@@ -550,6 +563,9 @@ object PreferencesDialog: TPreferencesDialog
             Left = 247
             Top = 8
             Width = 123
+            DesignSize = (
+              123
+              146)
             inherited CCNoChangeButton: TRadioButton
               Width = 110
             end
@@ -567,6 +583,9 @@ object PreferencesDialog: TPreferencesDialog
             Left = 8
             Top = 8
             Width = 231
+            DesignSize = (
+              231
+              146)
             inherited TMTextButton: TRadioButton
               Width = 219
             end
@@ -583,9 +602,12 @@ object PreferencesDialog: TPreferencesDialog
           inherited FilterGroup: TXPGroupBox
             Left = 8
             Top = 284
-            Width = 363
+            Width = 362
+            DesignSize = (
+              362
+              41)
             inherited ExcludeFileMaskCombo: THistoryComboBox
-              Width = 255
+              Width = 254
             end
           end
         end
@@ -600,12 +622,12 @@ object PreferencesDialog: TPreferencesDialog
           335)
         object EditorGroup: TXPGroupBox
           Left = 8
-          Top = 8
+          Top = 87
           Width = 362
           Height = 122
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Default editor'
-          TabOrder = 0
+          TabOrder = 1
           DesignSize = (
             362
             122)
@@ -652,12 +674,12 @@ object PreferencesDialog: TPreferencesDialog
         end
         object EditorFontGroup: TXPGroupBox
           Left = 8
-          Top = 136
+          Top = 215
           Width = 362
           Height = 56
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Editor font'
-          TabOrder = 1
+          TabOrder = 2
           DesignSize = (
             362
             56)
@@ -683,12 +705,12 @@ object PreferencesDialog: TPreferencesDialog
         end
         object EditorOptionsGroup: TXPGroupBox
           Left = 8
-          Top = 198
+          Top = 277
           Width = 362
           Height = 51
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Options'
-          TabOrder = 2
+          TabOrder = 3
           DesignSize = (
             362
             51)
@@ -703,6 +725,31 @@ object PreferencesDialog: TPreferencesDialog
             OnClick = ControlChange
           end
         end
+        object SingleEditorGroup: TXPGroupBox
+          Left = 8
+          Top = 8
+          Width = 362
+          Height = 73
+          Anchors = [akLeft, akTop, akRight]
+          Caption = 'Allow multiple opened files (editors)'
+          TabOrder = 0
+          object EditorSingleEditorOnCheck: TRadioButton
+            Left = 16
+            Top = 21
+            Width = 329
+            Height = 17
+            Caption = '&One file only, use main session to upload changed files'
+            TabOrder = 0
+          end
+          object EditorSingleEditorOffCheck: TRadioButton
+            Left = 16
+            Top = 45
+            Width = 337
+            Height = 17
+            Caption = '&Multiple files, use background transfer to upload changed files'
+            TabOrder = 1
+          end
+        end
       end
       object IntegrationSheet: TTabSheet
         Tag = 9
@@ -838,7 +885,7 @@ object PreferencesDialog: TPreferencesDialog
           Width = 362
           Height = 317
           Anchors = [akLeft, akTop, akRight, akBottom]
-          Caption = 'Custom commands (SCP only)'
+          Caption = 'Custom commands'
           TabOrder = 0
           DesignSize = (
             362
@@ -1008,13 +1055,13 @@ object PreferencesDialog: TPreferencesDialog
           Left = 8
           Top = 8
           Width = 362
-          Height = 287
+          Height = 241
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Drag && Drop downloads'
           TabOrder = 0
           DesignSize = (
             362
-            287)
+            241)
           object DDExtEnabledLabel: TLabel
             Left = 35
             Top = 68
@@ -1067,61 +1114,29 @@ object PreferencesDialog: TPreferencesDialog
             Left = 34
             Top = 184
             Width = 325
-            Height = 97
+            Height = 51
             BevelOuter = bvNone
             TabOrder = 2
             DesignSize = (
               325
-              97)
-            object DDSystemTemporaryDirectoryButton: TRadioButton
-              Left = 0
-              Top = 0
-              Width = 297
-              Height = 17
-              Caption = '&Use temporary directory of system'
-              TabOrder = 0
-              OnClick = ControlChange
-            end
-            object DDCustomTemporaryDirectoryButton: TRadioButton
-              Left = 0
-              Top = 24
-              Width = 129
-              Height = 17
-              Caption = 'Use this &directory:'
-              TabOrder = 1
-              OnClick = ControlChange
-            end
-            object DDTemporaryDirectoryEdit: TDirectoryEdit
-              Left = 136
-              Top = 20
-              Width = 181
-              Height = 21
-              AcceptFiles = True
-              DialogText = 'Select directory for temporary drag && drop files.'
-              ClickKey = 16397
-              Anchors = [akLeft, akTop, akRight]
-              TabOrder = 2
-              Text = 'DDTemporaryDirectoryEdit'
-              OnClick = ControlChange
-              OnKeyDown = PathEditsKeyDown
-            end
+              51)
             object DDWarnLackOfTempSpaceCheck: TCheckBox
               Left = 0
-              Top = 53
+              Top = 5
               Width = 321
               Height = 17
               Caption = '&Warn when there is not enough free space'
-              TabOrder = 3
+              TabOrder = 0
               OnClick = ControlChange
             end
             object DDWarnOnMoveCheck: TCheckBox
               Left = 0
-              Top = 76
+              Top = 28
               Width = 303
               Height = 17
               Anchors = [akLeft, akTop, akRight]
               Caption = 'Warn when mo&ving via temporary directory'
-              TabOrder = 4
+              TabOrder = 1
               OnClick = ControlChange
             end
           end
@@ -1241,7 +1256,7 @@ object PreferencesDialog: TPreferencesDialog
           335)
         object RandomSeedFileLabel: TLabel
           Left = 16
-          Top = 93
+          Top = 202
           Width = 82
           Height = 13
           Caption = '&Random seed file'
@@ -1276,7 +1291,7 @@ object PreferencesDialog: TPreferencesDialog
         end
         object RandomSeedFileEdit: TFilenameEdit
           Left = 136
-          Top = 89
+          Top = 198
           Width = 234
           Height = 21
           AcceptFiles = True
@@ -1286,11 +1301,66 @@ object PreferencesDialog: TPreferencesDialog
           DialogTitle = 'Select file for random seed'
           ClickKey = 16397
           Anchors = [akLeft, akTop, akRight]
-          TabOrder = 1
+          TabOrder = 2
           Text = 'RandomSeedFileEdit'
           OnChange = ControlChange
           OnKeyDown = PathEditsKeyDown
         end
+        object TemporaryDirectoryGrouo: TXPGroupBox
+          Left = 8
+          Top = 88
+          Width = 362
+          Height = 99
+          Anchors = [akLeft, akTop, akRight]
+          Caption = 'Temporary directory'
+          TabOrder = 1
+          DesignSize = (
+            362
+            99)
+          object Label6: TLabel
+            Left = 16
+            Top = 22
+            Width = 329
+            Height = 23
+            Anchors = [akLeft, akTop, akRight]
+            AutoSize = False
+            Caption = 'Specify where to temporarily store edited and downloaded files.'
+            WordWrap = True
+            OnClick = DDExtLabelClick
+          end
+          object DDSystemTemporaryDirectoryButton: TRadioButton
+            Left = 16
+            Top = 45
+            Width = 297
+            Height = 17
+            Caption = '&Use temporary directory of system'
+            TabOrder = 0
+            OnClick = ControlChange
+          end
+          object DDCustomTemporaryDirectoryButton: TRadioButton
+            Left = 16
+            Top = 69
+            Width = 129
+            Height = 17
+            Caption = 'Use this &directory:'
+            TabOrder = 1
+            OnClick = ControlChange
+          end
+          object DDTemporaryDirectoryEdit: TDirectoryEdit
+            Left = 152
+            Top = 65
+            Width = 197
+            Height = 21
+            AcceptFiles = True
+            DialogText = 'Select directory for temporary drag && drop files.'
+            ClickKey = 16397
+            Anchors = [akLeft, akTop, akRight]
+            TabOrder = 2
+            Text = 'DDTemporaryDirectoryEdit'
+            OnClick = ControlChange
+            OnKeyDown = PathEditsKeyDown
+          end
+        end
       end
       object TransferResumeSheet: TTabSheet
         Tag = 14

+ 9 - 3
forms/Preferences.h

@@ -115,9 +115,6 @@ __published:
   TRadioButton *DDExtEnabledButton;
   TRadioButton *DDExtDisabledButton;
   TPanel *DDExtDisabledPanel;
-  TRadioButton *DDSystemTemporaryDirectoryButton;
-  TRadioButton *DDCustomTemporaryDirectoryButton;
-  TDirectoryEdit *DDTemporaryDirectoryEdit;
   TCheckBox *DDWarnLackOfTempSpaceCheck;
   TCheckBox *DDWarnOnMoveCheck;
   TCheckBox *ConfirmExitOnCompletionCheck;
@@ -152,6 +149,15 @@ __published:
   TRadioButton *ResumeSmartButton;
   TRadioButton *ResumeOffButton;
   TUpDownEdit *ResumeThresholdEdit;
+  TCheckBox *ConfirmCommandSessionCheck;
+  TXPGroupBox *SingleEditorGroup;
+  TRadioButton *EditorSingleEditorOnCheck;
+  TRadioButton *EditorSingleEditorOffCheck;
+  TXPGroupBox *TemporaryDirectoryGrouo;
+  TRadioButton *DDSystemTemporaryDirectoryButton;
+  TRadioButton *DDCustomTemporaryDirectoryButton;
+  TDirectoryEdit *DDTemporaryDirectoryEdit;
+  TLabel *Label6;
   void __fastcall FormShow(TObject *Sender);
   void __fastcall ControlChange(TObject *Sender);
   void __fastcall EditorFontButtonClick(TObject *Sender);

+ 2 - 4
forms/ScpCommander.cpp

@@ -509,9 +509,6 @@ void __fastcall TScpCommanderForm::UpdateControls()
   CommandLineLabel->Caption = DirView(osCurrent)->PathName;
   CommandLinePromptLabel->Caption =
     (FCurrentSide == osRemote) ? "$" : ">";
-  EnableControl(CommandLineCombo,
-    (FCurrentSide == osLocal) ||
-    ((Terminal != NULL) && Terminal->IsCapable[fcAnyCommand]));
 }
 //---------------------------------------------------------------------------
 void __fastcall TScpCommanderForm::ChangePath(TOperationSide Side)
@@ -1035,7 +1032,8 @@ void __fastcall TScpCommanderForm::ExecuteCommandLine()
 {
   if (!CommandLineCombo->Text.Trim().IsEmpty() &&
       ((FCurrentSide != osRemote) ||
-       (Terminal->AllowedAnyCommand(CommandLineCombo->Text))))
+       (Terminal->AllowedAnyCommand(CommandLineCombo->Text) &&
+        EnsureAnyCommandCapability())))
   {
     CommandLinePopulate();
     CommandLineCombo->SaveToHistory();

+ 2 - 2
forms/Synchronize.cpp

@@ -60,7 +60,7 @@ void __fastcall TSynchronizeDialog::UpdateControls()
   StartButton->Default = StartButton->Visible;
   StopButton->Visible = FSynchronizing;
   StopButton->Default = StopButton->Visible;
-  Caption = LoadStr(FSynchronizing ? SYCHRONIZE_SYCHRONIZING : SYCHRONIZE_TITLE);
+  Caption = LoadStr(FSynchronizing ? SYNCHRONIZE_SYCHRONIZING : SYNCHRONIZE_TITLE);
   EnableControl(TransferPreferencesButton, !FSynchronizing);
   EnableControl(CancelButton, !FSynchronizing);
   EnableControl(DirectoriesGroup, !FSynchronizing);
@@ -134,7 +134,7 @@ void __fastcall TSynchronizeDialog::DoStartStop(bool Start)
 {
   if (FOnStartStop)
   {
-    FOnStartStop(this, Start, GetParams(), DoAbort);
+    FOnStartStop(this, Start, GetParams(), DoAbort, NULL);
   }
 }
 //---------------------------------------------------------------------------

+ 1 - 1
forms/Synchronize.dfm

@@ -114,7 +114,7 @@ object SynchronizeDialog: TSynchronizeDialog
     Width = 381
     Height = 95
     Anchors = [akLeft, akTop, akRight]
-    Caption = 'Upload options'
+    Caption = 'Synchronize options'
     TabOrder = 1
     DesignSize = (
       381

+ 1 - 1
makefile

@@ -6,7 +6,7 @@ ROOT = $(MAKEDIR)\..
 MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$&.mak
 BPR2MAK = $(ROOT)\bin\bpr2mak
 #------------------------------------------------------------------------------
-default: WinSCP3.exe DragExt.dll
+default: WinSCP3.exe DragExt.dll lib\DiscMon_B5.lib
 
 WinSCP3.exe: WinSCP3.bpr
 WinSCP3.exe: lib\Moje_B5.lib lib\DragDrop_B5.lib lib\DriveDir_B5.lib

+ 108 - 0
packages/DiscMon_B5.bpk

@@ -0,0 +1,108 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+  <MACROS>
+    <VERSION value="BCB.06.00"/>
+    <PROJECT value="..\lib\DiscMon_B5.bpl"/>
+    <OBJFILES value="DiscMon_B5.obj &quot;my\CompThread.obj&quot; &quot;my\DiscMon.obj&quot;"/>
+    <RESFILES value="DiscMon_B5.res &quot;my\DiscMon.dcr&quot;"/>
+    <DEFFILE value=""/>
+    <RESDEPEN value="$(RESFILES)"/>
+    <LIBFILES value=""/>
+    <LIBRARIES value="Moje_B5.lib adortl.lib bcb2kaxserver.lib
+      bdecds.lib bdertl.lib cds.lib dbexpress.lib dbrtl.lib dbxcds.lib
+      dclocx.lib dsnap.lib ibxpress.lib indy.lib inet.lib inetdb.lib
+      inetdbbde.lib inetdbxpress.lib nmfast.lib qrpt.lib soaprtl.lib tee.lib
+      teedb.lib teeqr.lib teeui.lib vcldb.lib vcldbx.lib visualdbclx.lib
+      xmlrtl.lib"/>
+    <SPARELIBS value="Moje_B5.lib adortl.lib bcb2kaxserver.lib bcbie.lib
+      bcbsmp.lib bdecds.lib bdertl.lib cds.lib dbexpress.lib dbrtl.lib
+      dbxcds.lib dclocx.lib dsnap.lib ibxpress.lib indy.lib inet.lib inetdb.lib
+      inetdbbde.lib inetdbxpress.lib nmfast.lib qrpt.lib rtl.lib soaprtl.lib
+      tee.lib teedb.lib teeqr.lib teeui.lib vcl.lib vcldb.lib vcldbx.lib
+      visualdbclx.lib xmlrtl.lib"/>
+    <PACKAGES value="bcbie.bpi bcbsmp.bpi rtl.bpi vcl.bpi vclx.bpi"/>
+    <PATHCPP value=".;"/>
+    <PATHPAS value=".;&quot;my&quot;"/>
+    <PATHRC value=".;"/>
+    <PATHASM value=".;"/>
+    <DEBUGLIBPATH value="$(BCB)\lib\debug"/>
+    <RELEASELIBPATH value="$(BCB)\lib\release"/>
+    <LINKER value="ilink32"/>
+    <USERDEFINES value=""/>
+    <SYSDEFINES value="NO_STRICT;USEPACKAGES"/>
+    <MAINSOURCE value="DiscMon_B5.cpp"/>
+    <INCLUDEPATH value="&quot;my&quot;;$(BCB)\include;$(BCB)\include\vcl"/>
+    <LIBPATH value="..\lib\;&quot;my&quot;;$(BCB)\lib\obj;$(BCB)\lib;$(BCB)\Source\ToolsAPI"/>
+    <WARNINGS value="-wuse -w-par"/>
+    <OTHERFILES value=""/>
+  </MACROS>
+  <OPTIONS>
+    <CFLAG1 value="-O2 -H=c:\PROGRA~1\borland\CBUILD~1\lib\vcl60.csm -Hc -Q -w -Vx -Ve -X- 
+      -a8 -b- -k- -vi -c -tWM"/>
+    <PFLAGS value="  -$Y- -$L- -$D- -$C- -$A8 -v -JPHNE -M"/>
+    <RFLAGS value=""/>
+    <AFLAGS value="/mx /w2 /zn"/>
+    <LFLAGS value="-I -D&quot;Martin's components&quot; -aa -Tpp -x -Gn -Gl -Gi"/>
+    <OTHERFILES value=""/>
+  </OPTIONS>
+  <LINKER>
+    <ALLOBJ value="c0pkg32.obj $(PACKAGES) sysinit.obj $(OBJFILES)"/>
+    <ALLRES value="$(RESFILES)"/>
+    <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib"/>
+    <OTHERFILES value=""/>
+  </LINKER>
+  <FILELIST>
+      <FILE FILENAME="DiscMon_B5.cpp" FORMNAME="" UNITNAME="DiscMon_B5" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="DiscMon_B5.res" FORMNAME="" UNITNAME="DiscMon_B5.res" CONTAINERID="ResTool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="rtl.bpi" FORMNAME="" UNITNAME="rtl" CONTAINERID="BPITool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="vcl.bpi" FORMNAME="" UNITNAME="vcl" CONTAINERID="BPITool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="vclx.bpi" FORMNAME="" UNITNAME="vclx" CONTAINERID="BPITool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="bcbsmp.bpi" FORMNAME="" UNITNAME="bcbsmp" CONTAINERID="BPITool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="bcbie.bpi" FORMNAME="" UNITNAME="bcbie" CONTAINERID="BPITool" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="my\CompThread.pas" FORMNAME="" UNITNAME="CompThread" CONTAINERID="PascalCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="my\DiscMon.pas" FORMNAME="" UNITNAME="DiscMon" CONTAINERID="PascalCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="my\DiscMon.dcr" FORMNAME="" UNITNAME="" CONTAINERID="DcrTool" DESIGNCLASS="" LOCALCOMMAND=""/>
+  </FILELIST>
+  <BUILDTOOLS>
+  </BUILDTOOLS>
+
+  <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=1
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1029
+CodePage=1250
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[Compiler]
+ShowInfoMsgs=1
+LinkDebugVcl=0
+LinkCGLIB=0
+
+[Linker]
+LibPrefix=
+LibSuffix=
+LibVersion=
+  </IDEOPTIONS>
+</PROJECT>

+ 13 - 0
packages/DiscMon_B5.cpp

@@ -0,0 +1,13 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+#pragma package(smart_init)
+//---------------------------------------------------------------------------
+//   Package source.
+//---------------------------------------------------------------------------
+#pragma argsused
+int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
+{
+  return 1;
+}
+//---------------------------------------------------------------------------

BIN
packages/DiscMon_B5.res


+ 12 - 7
packages/my/DiscMon.hpp

@@ -11,15 +11,8 @@
 #pragma option push -w-
 #pragma option push -Vx
 #include <CompThread.hpp>	// Pascal unit
-#include <ActiveX.hpp>	// Pascal unit
-#include <ShlObj.hpp>	// Pascal unit
-#include <Dialogs.hpp>	// Pascal unit
-#include <Forms.hpp>	// Pascal unit
-#include <Controls.hpp>	// Pascal unit
-#include <Graphics.hpp>	// Pascal unit
 #include <Classes.hpp>	// Pascal unit
 #include <SysUtils.hpp>	// Pascal unit
-#include <Messages.hpp>	// Pascal unit
 #include <Windows.hpp>	// Pascal unit
 #include <SysInit.hpp>	// Pascal unit
 #include <System.hpp>	// Pascal unit
@@ -31,6 +24,8 @@ namespace Discmon
 //-- type declarations -------------------------------------------------------
 typedef void __fastcall (__closure *TDiscMonitorNotify)(System::TObject* Sender, const AnsiString Directory);
 
+typedef void __fastcall (__closure *TDiscMonitorSynchronize)(System::TObject* Sender, Classes::TThreadMethod Method);
+
 class DELPHICLASS TDiscMonitorThread;
 class PASCALIMPLEMENTATION TDiscMonitorThread : public Compthread::TCompThread 
 {
@@ -39,6 +34,7 @@ class PASCALIMPLEMENTATION TDiscMonitorThread : public Compthread::TCompThread
 private:
 	TDiscMonitorNotify FOnChange;
 	TDiscMonitorNotify FOnInvalid;
+	TDiscMonitorSynchronize FOnSynchronize;
 	Classes::TStrings* FDirectories;
 	unsigned FFilters;
 	unsigned FDestroyEvent;
@@ -51,18 +47,22 @@ private:
 	void __fastcall SetDirectories(const Classes::TStrings* Value);
 	void __fastcall SetFilters(unsigned Value);
 	void __fastcall SetSubTree(bool Value);
+	int __fastcall GetMaxDirectories(void);
 	
 protected:
 	virtual void __fastcall Execute(void);
 	void __fastcall Update(void);
+	void __fastcall DoSynchronize(Classes::TThreadMethod Method);
 	
 public:
 	__fastcall TDiscMonitorThread(void);
 	__fastcall virtual ~TDiscMonitorThread(void);
+	__property int MaxDirectories = {read=GetMaxDirectories, nodefault};
 	__property Classes::TStrings* Directories = {read=FDirectories, write=SetDirectories};
 	__property unsigned Filters = {read=FFilters, write=SetFilters, nodefault};
 	__property TDiscMonitorNotify OnChange = {read=FOnChange, write=FOnChange};
 	__property TDiscMonitorNotify OnInvalid = {read=FOnInvalid, write=FOnInvalid};
+	__property TDiscMonitorSynchronize OnSynchronize = {read=FOnSynchronize, write=FOnSynchronize};
 	__property bool SubTree = {read=FSubTree, write=SetSubTree, nodefault};
 	__property int ChangeDelay = {read=FChangeDelay, write=FChangeDelay, default=500};
 };
@@ -85,6 +85,7 @@ private:
 	TMonitorFilters FFilters;
 	TDiscMonitorNotify FOnChange;
 	TDiscMonitorNotify FOnInvalid;
+	TDiscMonitorSynchronize FOnSynchronize;
 	bool FShowMsg;
 	bool FPending;
 	Classes::TStrings* __fastcall GetDirectories(void);
@@ -101,6 +102,7 @@ private:
 protected:
 	void __fastcall Change(System::TObject* Sender, const AnsiString Directory);
 	void __fastcall Invalid(System::TObject* Sender, const AnsiString Directory);
+	void __fastcall DoSynchronize(System::TObject* Sender, Classes::TThreadMethod Method);
 	
 public:
 	__fastcall virtual TDiscMonitor(Classes::TComponent* AOwner);
@@ -117,6 +119,7 @@ __published:
 	__property bool ShowDesignMsg = {read=FShowMsg, write=FShowMsg, default=0};
 	__property TDiscMonitorNotify OnChange = {read=FOnChange, write=FOnChange};
 	__property TDiscMonitorNotify OnInvalid = {read=FOnInvalid, write=FOnInvalid};
+	__property TDiscMonitorSynchronize OnSynchronize = {read=FOnSynchronize, write=FOnSynchronize};
 	__property TMonitorFilters Filters = {read=FFilters, write=SetFilters, default=1};
 	__property bool SubTree = {read=GetSubTree, write=SetSubTree, default=1};
 	__property bool Active = {read=FActive, write=SetActive, default=0};
@@ -125,6 +128,8 @@ __published:
 
 
 //-- var, const, procedure ---------------------------------------------------
+extern PACKAGE System::ResourceString _STooManyWatchDirectories;
+#define Discmon_STooManyWatchDirectories System::LoadResourceString(&Discmon::_STooManyWatchDirectories)
 extern PACKAGE void __fastcall Register(void);
 
 }	/* namespace Discmon */

+ 45 - 24
packages/my/DiscMon.pas

@@ -46,8 +46,7 @@ unit DiscMon;
 interface
 
 uses
-  Windows, Messages, SysUtils, Classes, Graphics, Controls,
-  Forms, Dialogs, ShlObj, ActiveX, CompThread;
+  Windows, SysUtils, Classes, CompThread;
 
 //=== DISC MONITORING THREAD ===================================================
 // This thread will monitor a given directory and subdirectories (if required)
@@ -61,11 +60,13 @@ uses
 
 type
   TDiscMonitorNotify = procedure(Sender: TObject; const Directory: string) of object;
+  TDiscMonitorSynchronize = procedure(Sender: TObject; Method: TThreadMethod) of object;
 
   TDiscMonitorThread = class(TCompThread)
   private
     FOnChange: TDiscMonitorNotify;
     FOnInvalid: TDiscMonitorNotify;
+    FOnSynchronize: TDiscMonitorSynchronize;
     FDirectories: TStrings;
     FFilters: DWORD;
     FDestroyEvent,
@@ -78,12 +79,15 @@ type
     procedure SetDirectories(const Value: TStrings);
     procedure SetFilters(Value: DWORD);
     procedure SetSubTree(Value: boolean);
+    function GetMaxDirectories: Integer;
   protected
     procedure Execute; override;
     procedure Update;
+    procedure DoSynchronize(Method: TThreadMethod);
   public
     constructor Create;
     destructor Destroy; override;
+    property MaxDirectories: Integer read GetMaxDirectories;
     // The directory to monitor
     property Directories: TStrings read FDirectories write SetDirectories;
     // Filter condition, may be any of the FILE_NOTIFY_CHANGE_XXXXXXX constants
@@ -93,6 +97,7 @@ type
     property OnChange: TDiscMonitorNotify read FOnChange write FOnChange;
     // Event called for invalid parameters
     property OnInvalid: TDiscMonitorNotify read FOnInvalid write FOnInvalid;
+    property OnSynchronize: TDiscMonitorSynchronize read FOnSynchronize write FOnSynchronize;
     // Include subdirectories below specified directory.
     property SubTree: Boolean read FSubTree write SetSubTree;
     // specify, how long the thread should wait, before the event OnChange is fired:
@@ -118,6 +123,7 @@ type
     FFilters: TMonitorFilters;
     FOnChange: TDiscMonitorNotify;
     FOnInvalid: TDiscMonitorNotify;
+    FOnSynchronize: TDiscMonitorSynchronize;
     FShowMsg: Boolean;
     FPending: Boolean;
     function GetDirectories: TStrings;
@@ -133,6 +139,7 @@ type
   protected
     procedure Change(Sender: TObject; const Directory: string);
     procedure Invalid(Sender: TObject; const Directory: string);
+    procedure DoSynchronize(Sender: TObject; Method: TThreadMethod);
   public
     constructor Create(AOwner : TComponent); override;
     destructor Destroy; override;
@@ -154,6 +161,7 @@ type
     property OnChange: TDiscMonitorNotify read FOnChange write FOnChange;
     // event called if an invalid condition is found
     property OnInvalid: TDiscMonitorNotify read FOnInvalid write FOnInvalid;
+    property OnSynchronize: TDiscMonitorSynchronize read FOnSynchronize write FOnSynchronize;
     // notification filter conditions
     property Filters: TMonitorFilters read FFilters write SetFilters default [moFilename];
     // include subdirectories below the specified directory
@@ -167,10 +175,10 @@ type
 
 procedure Register;
 
-implementation
-
 resourcestring
-  STooManyWatchDirectories = 'Cannot watch for changes in %d directories and subdirectories (limit is %d).';
+  STooManyWatchDirectories = 'Cannot watch for changes in more then %d directories and subdirectories.';
+
+implementation
 
 {$IFDEF BUGFIX}
 {$Z4}
@@ -224,10 +232,21 @@ begin
   if Assigned(FOnInvalid) then FOnInvalid(Self, FNotifiedDirectory);
 end;
 
+function TDiscMonitorThread.GetMaxDirectories: Integer;
+begin
+  Result := MAXIMUM_WAIT_OBJECTS - 2;
+end;
+
 // Change the current directory
 procedure TDiscMonitorThread.SetDirectories(const Value: TStrings);
 begin
-  if Value <> nil then FDirectories.Assign(Value)
+  if Value <> nil then
+  begin
+    if Value.Count > MaxDirectories then
+      raise Exception.CreateFmt(STooManyWatchDirectories, [MaxDirectories]);
+
+    FDirectories.Assign(Value)
+  end
     else FDirectories.Clear;
   Update;
 end;
@@ -270,6 +289,11 @@ begin
     SetEvent(FChangeEvent)
 end;
 
+procedure TDiscMonitorThread.DoSynchronize(Method: TThreadMethod);
+begin
+  if Assigned(OnSynchronize) then OnSynchronize(Self, Method);
+end;
+
 // The EXECUTE procedure
 //     -------
 // Execute needs to:
@@ -323,14 +347,14 @@ var
       begin
         // call the OnInvalid event
         FNotifiedDirectory := Directory;
-        Synchronize(InformInvalid);
+        DoSynchronize(InformInvalid);
 
         // wait until either DestroyEvent or the ChangeEvents are signalled
         Result := WaitForMultipleObjects(2, PWOHandleArray(Handles), False, INFINITE);
         if Result = WAIT_FAILED then
         begin
           FNotifiedDirectory := '';
-          Synchronize(InformInvalid);
+          DoSynchronize(InformInvalid);
           Again := False;
         end
           else Again := (Result - WAIT_OBJECT_0 = 1);
@@ -367,7 +391,7 @@ begin {Execute}
         if Result = WAIT_FAILED then
         begin
           FNotifiedDirectory := '';
-          Synchronize(InformInvalid);
+          DoSynchronize(InformInvalid);
         end
           else
         if (Result - WAIT_OBJECT_0 >= 2) and
@@ -377,7 +401,7 @@ begin {Execute}
           // loop back to re-WaitFor... the thread
           Sleep(FChangeDelay);
           FNotifiedDirectory := FDirectories[Result - WAIT_OBJECT_0 - 2];
-          Synchronize(InformChange);
+          DoSynchronize(InformChange);
           FindNextChangeNotification(Handles^[Result - WAIT_OBJECT_0])
         end;
       until (Result = WAIT_FAILED) or (Result - WAIT_OBJECT_0 < 2) or
@@ -411,6 +435,7 @@ begin
   FMonitor.ChangeDelay := 500;            {ie01}
   FMonitor.OnChange := Change;            // hook into its event handlers
   FMonitor.OnInvalid := Invalid;
+  FMonitor.OnSynchronize := DoSynchronize;
   Filters := [moFilename];                // default filters to moFilename
   SubTree := True;                        // default sub-tree search to on
   FPending := True;
@@ -429,9 +454,6 @@ procedure TDiscMonitor.Change(Sender: TObject; const Directory: string);
 begin
   if Assigned(FOnChange) then
     FOnChange(Self, Directory)
-  else
-    if (csDesigning in ComponentState) and FShowMsg then
-      ShowMessage('Change signalled');
 end;
 
 // Invalid notification from the thread has occurred. Call the component's event
@@ -441,9 +463,12 @@ procedure TDiscMonitor.Invalid(Sender: TObject; const Directory: string);
 begin
   if Assigned(FOnInvalid) then
     FOnInvalid(Self, Directory)
-  else
-    if (csDesigning in ComponentState) and FShowMsg then
-      ShowMessage('Invalid parameter signalled');
+end;
+
+procedure TDiscMonitor.DoSynchronize(Sender: TObject; Method: TThreadMethod);
+begin
+  if Assigned(FOnSynchronize) then FOnSynchronize(Self, Method)
+    else FMonitor.Synchronize(Method);
 end;
 
 // Stop the monitor running
@@ -460,7 +485,7 @@ end;
 
 function TDiscMonitor.GetMaxDirectories: Integer;
 begin
-  Result := MAXIMUM_WAIT_OBJECTS - 2;
+  Result := FMonitor.MaxDirectories;
 end;
 
 // Control the thread by using it's resume and suspend methods
@@ -468,12 +493,6 @@ procedure TDiscMonitor.SetActive(Value: Boolean);
 begin
   if Value <> FActive then
   begin
-    if Value and (Directories.Count > MaxDirectories) then
-    begin
-      raise Exception.CreateFmt(STooManyWatchDirectories,
-        [Directories.Count, MaxDirectories]);
-    end;
-
     FActive := Value;
     if Active then
     begin
@@ -524,6 +543,8 @@ begin
         begin
           FileName := Directory + SearchRec.Name;
           Dirs.Add(FileName);
+          if Dirs.Count > MaxDirectories then
+            raise Exception.CreateFmt(STooManyWatchDirectories, [MaxDirectories]);
           AddDirectory(Dirs, FileName);
         end;
 
@@ -600,7 +621,7 @@ var
 begin
   if Value <> FFilters then
     if Value = [] then
-      ShowMessage ('Some filter condition must be set.')
+      raise Exception.Create('Some filter condition must be set.')
     else begin
       FFilters := Value;
       I := 0;

+ 15 - 3
putty/CMDGEN.C

@@ -686,14 +686,26 @@ int main(int argc, char **argv)
 	    if (!load_encrypted) {
 		void *vblob;
 		char *blob;
-		int n, bloblen;
+		int n, l, bloblen;
 
 		ret = rsakey_pubblob(&infilename, &vblob, &bloblen, &error);
 		blob = (char *)vblob;
 
 		n = 4;		       /* skip modulus bits */
-		n += ssh1_read_bignum(blob + n, &ssh1key->exponent);
-		n += ssh1_read_bignum(blob + n, &ssh1key->modulus);
+		
+		l = ssh1_read_bignum(blob + n, bloblen - n,
+				     &ssh1key->exponent);
+		if (l < 0) {
+		    error = "SSH1 public key blob was too short";
+		} else {
+		    n += l;
+		    l = ssh1_read_bignum(blob + n, bloblen - n,
+					 &ssh1key->modulus);
+		    if (l < 0) {
+			error = "SSH1 public key blob was too short";
+		    } else
+			n += l;
+		}
 		ssh1key->comment = NULL;
 		ssh1key->private_exponent = NULL;
 	    } else {

+ 7 - 0
putty/CMDLINE.C

@@ -111,6 +111,12 @@ static int cmdline_check_unavailable(int flag, char *p)
  * Process a standard command-line parameter. `p' is the parameter
  * in question; `value' is the subsequent element of argv, which
  * may or may not be required as an operand to the parameter.
+ * If `need_save' is 1, arguments which need to be saved as
+ * described at this top of this file are, for later execution;
+ * if 0, they are processed normally. (-1 is a special value used
+ * by pterm to count arguments for a preliminary pass through the
+ * argument list; it causes immediate return with an appropriate
+ * value with no action taken.)
  * Return value is 2 if both arguments were used; 1 if only p was
  * used; 0 if the parameter wasn't one we recognised; -2 if it
  * should have been 2 but value was NULL.
@@ -131,6 +137,7 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg)
 	/* This parameter must be processed immediately rather than being
 	 * saved. */
 	do_defaults(value, cfg);
+	loaded_session = TRUE;
 	return 2;
     }
     if (!strcmp(p, "-ssh")) {

+ 15 - 8
putty/CONFIG.C

@@ -358,6 +358,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
 		/* If at this point we have a valid session, go! */
 		if (*cfg2.host) {
 		    *cfg = cfg2;       /* structure copy */
+		    cfg->remote_cmd_ptr = cfg->remote_cmd; /* nasty */
 		    dlg_end(dlg, 1);
 		} else
 		    dlg_beep(dlg);
@@ -1036,6 +1037,12 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
     ctrl_checkbox(s, "Disable remote-controlled character set configuration",
 		  'r', HELPCTX(features_charset), dlg_stdcheckbox_handler,
 		  I(offsetof(Config,no_remote_charset)));
+    ctrl_checkbox(s, "Disable Arabic text shaping",
+		  'l', HELPCTX(features_arabicshaping), dlg_stdcheckbox_handler,
+		  I(offsetof(Config, arabicshaping)));
+    ctrl_checkbox(s, "Disable bidirectional text display",
+		  'd', HELPCTX(features_bidi), dlg_stdcheckbox_handler,
+		  I(offsetof(Config, bidi)));
 
     /*
      * The Window panel.
@@ -1261,6 +1268,10 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 			 HELPCTX(connection_termtype),
 			 dlg_stdeditbox_handler, I(offsetof(Config,termtype)),
 			 I(sizeof(((Config *)0)->termtype)));
+	    ctrl_editbox(s, "Terminal speeds", 's', 50,
+			 HELPCTX(connection_termspeed),
+			 dlg_stdeditbox_handler, I(offsetof(Config,termspeed)),
+			 I(sizeof(((Config *)0)->termspeed)));
 	    ctrl_editbox(s, "Auto-login username", 'u', 50,
 			 HELPCTX(connection_username),
 			 dlg_stdeditbox_handler, I(offsetof(Config,username)),
@@ -1281,6 +1292,10 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 			  'n', HELPCTX(connection_nodelay),
 			  dlg_stdcheckbox_handler,
 			  I(offsetof(Config,tcp_nodelay)));
+	    ctrl_checkbox(s, "Enable TCP keepalives (SO_KEEPALIVE option)",
+			  'p', HELPCTX(connection_tcpkeepalive),
+			  dlg_stdcheckbox_handler,
+			  I(offsetof(Config,tcp_keepalives)));
 	}
 
     }
@@ -1365,10 +1380,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 	if (!midsession) {
 	    s = ctrl_getset(b, "Connection/Telnet", "data",
 			    "Data to send to the server");
-	    ctrl_editbox(s, "Terminal-speed string", 's', 50,
-			 HELPCTX(telnet_termspeed),
-			 dlg_stdeditbox_handler, I(offsetof(Config,termspeed)),
-			 I(sizeof(((Config *)0)->termspeed)));
 	    ctrl_text(s, "Environment variables:", HELPCTX(telnet_environ));
 	    ctrl_columns(s, 2, 80, 20);
 	    ed = (struct environ_data *)
@@ -1437,10 +1448,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 
 	s = ctrl_getset(b, "Connection/Rlogin", "data",
 			"Data to send to the server");
-	ctrl_editbox(s, "Terminal-speed string", 's', 50,
-		     HELPCTX(rlogin_termspeed),
-		     dlg_stdeditbox_handler, I(offsetof(Config,termspeed)),
-		     I(sizeof(((Config *)0)->termspeed)));
 	ctrl_editbox(s, "Local username:", 'l', 50,
 		     HELPCTX(rlogin_localuser),
 		     dlg_stdeditbox_handler, I(offsetof(Config,localusername)),

+ 1 - 1
putty/CONSOLE.C

@@ -1,6 +1,6 @@
 /*
  * console.c: various interactive-prompt routines shared between
- * the console PuTTY tools
+ * the Windows console PuTTY tools
  */
 
 #include <stdio.h>

+ 25 - 6
putty/LDISC.C

@@ -32,13 +32,20 @@ static int plen(Ldisc ldisc, unsigned char c)
 	return 1;
     else if (c < 128)
 	return 2;		       /* ^x for some x */
+    else if (in_utf(ldisc->term) && c >= 0xC0)
+	return 1;		       /* UTF-8 introducer character
+					* (FIXME: combining / wide chars) */
+    else if (in_utf(ldisc->term) && c >= 0x80 && c < 0xC0)
+	return 0;		       /* UTF-8 followup character */
     else
-	return 4;		       /* <XY> for hex XY */
+	return 4;		       /* <XY> hex representation */
 }
 
 static void pwrite(Ldisc ldisc, unsigned char c)
 {
-    if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term))) {
+    if ((c >= 32 && c <= 126) ||
+	(!in_utf(ldisc->term) && c >= 0xA0) ||
+	(in_utf(ldisc->term) && c >= 0x80)) {
 	c_write(ldisc, (char *)&c, 1);
     } else if (c < 128) {
 	char cc[2];
@@ -52,6 +59,14 @@ static void pwrite(Ldisc ldisc, unsigned char c)
     }
 }
 
+static int char_start(Ldisc ldisc, unsigned char c)
+{
+    if (in_utf(ldisc->term))
+	return (c < 0x80 || c >= 0xC0);
+    else
+	return 1;
+}
+
 static void bsb(Ldisc ldisc, int n)
 {
     while (n--)
@@ -137,7 +152,9 @@ void ldisc_send(void *handle, char *buf, int len, int interactive)
 		c += KCTRL('@');
 	    switch (ldisc->quotenext ? ' ' : c) {
 		/*
-		 * ^h/^?: delete one char and output one BSB
+		 * ^h/^?: delete, and output BSBs, to return to
+		 * last character boundary (in UTF-8 mode this may
+		 * be more than one byte)
 		 * ^w: delete, and output BSBs, to return to last
 		 * space/nonspace boundary
 		 * ^u: delete, and output BSBs, to return to BOL
@@ -153,9 +170,11 @@ void ldisc_send(void *handle, char *buf, int len, int interactive)
 	      case KCTRL('H'):
 	      case KCTRL('?'):	       /* backspace/delete */
 		if (ldisc->buflen > 0) {
-		    if (ECHOING)
-			bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
-		    ldisc->buflen--;
+		    do {
+			if (ECHOING)
+			    bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
+			ldisc->buflen--;
+		    } while (!char_start(ldisc, ldisc->buf[ldisc->buflen]));
 		}
 		break;
 	      case CTRL('W'):	       /* delete word */

+ 341 - 321
putty/MAKEFILE.BOR

@@ -1,4 +1,4 @@
-# Makefile for PuTTY under Borland C.
+# Makefile for putty under Borland C.
 #
 # This file was created by `mkfiles.pl' from the `Recipe' file.
 # DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.
@@ -90,7 +90,7 @@ BCB = $(MAKEDIR)\..
 
 .c.obj:
 	bcc32 -w-aus -w-ccc -w-par -w-pia $(COMPAT) $(FWHACK) $(XFLAGS) \
-		$(CFLAGS) /c $*.c
+		$(CFLAGS) -I./ -Icharset/ -Iunix/ -Imac/ /c $*.c
 .rc.res:
 	brcc32 $(FWHACK) $(RCFL) -i $(BCB)\include -r -DNO_WINRESRC_H \
 		-DWIN32 -D_WIN32 -DWINVER=0x0401 $*.rc
@@ -135,16 +135,16 @@ psftp.exe: be_none.obj cmdline.obj console.obj int64.obj logging.obj \
 	ilink32 -ap -Gn -L$(BCB)\lib @psftp.rsp
 
 putty.exe: be_all.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj noise.obj pageantc.obj \
-		portfwd.obj pproxy.obj printing.obj proxy.obj raw.obj \
-		rlogin.obj settings.obj sizetip.obj ssh.obj sshaes.obj \
-		sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj \
-		sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj sshrand.obj \
-		sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj telnet.obj \
-		terminal.obj tree234.obj unicode.obj version.obj wcwidth.obj \
-		wildcard.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj x11fwd.obj putty.rsp
+		ldiscucs.obj logging.obj minibidi.obj misc.obj noise.obj \
+		pageantc.obj portfwd.obj pproxy.obj printing.obj proxy.obj \
+		raw.obj rlogin.obj settings.obj sizetip.obj ssh.obj \
+		sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj \
+		sshdes.obj sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj \
+		sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj \
+		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
+		wcwidth.obj wildcard.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj x11fwd.obj putty.rsp
 	ilink32 -aa -Gn -L$(BCB)\lib @putty.rsp
 
 puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
@@ -156,12 +156,12 @@ puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
 	ilink32 -aa -Gn -L$(BCB)\lib @puttygen.rsp
 
 puttytel.exe: be_nossh.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj pproxy.obj printing.obj \
-		proxy.obj raw.obj rlogin.obj settings.obj sizetip.obj \
-		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
-		wcwidth.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj puttytel.rsp
+		ldiscucs.obj logging.obj minibidi.obj misc.obj pproxy.obj \
+		printing.obj proxy.obj raw.obj rlogin.obj settings.obj \
+		sizetip.obj telnet.obj terminal.obj tree234.obj unicode.obj \
+		version.obj wcwidth.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj puttytel.rsp
 	ilink32 -aa -Gn -L$(BCB)\lib @puttytel.rsp
 
 pageant.rsp: $(MAKEFILE)
@@ -225,18 +225,18 @@ psftp.rsp: $(MAKEFILE)
 putty.rsp: $(MAKEFILE)
 	echo c0w32 + > putty.rsp
 	echo be_all.obj cmdline.obj config.obj dialog.obj + >> putty.rsp
-	echo ldisc.obj ldiscucs.obj logging.obj misc.obj + >> putty.rsp
-	echo noise.obj pageantc.obj portfwd.obj pproxy.obj + >> putty.rsp
-	echo printing.obj proxy.obj raw.obj rlogin.obj + >> putty.rsp
-	echo settings.obj sizetip.obj ssh.obj sshaes.obj + >> putty.rsp
-	echo sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj + >> putty.rsp
-	echo sshdes.obj sshdh.obj sshdss.obj sshmd5.obj + >> putty.rsp
-	echo sshpubk.obj sshrand.obj sshrsa.obj sshsh512.obj + >> putty.rsp
-	echo sshsha.obj sshzlib.obj telnet.obj terminal.obj + >> putty.rsp
-	echo tree234.obj unicode.obj version.obj wcwidth.obj + >> putty.rsp
-	echo wildcard.obj wincfg.obj winctrls.obj windefs.obj + >> putty.rsp
-	echo windlg.obj window.obj winmisc.obj winnet.obj + >> putty.rsp
-	echo winstore.obj winutils.obj x11fwd.obj >> putty.rsp
+	echo ldisc.obj ldiscucs.obj logging.obj minibidi.obj + >> putty.rsp
+	echo misc.obj noise.obj pageantc.obj portfwd.obj + >> putty.rsp
+	echo pproxy.obj printing.obj proxy.obj raw.obj + >> putty.rsp
+	echo rlogin.obj settings.obj sizetip.obj ssh.obj + >> putty.rsp
+	echo sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj + >> putty.rsp
+	echo sshcrcda.obj sshdes.obj sshdh.obj sshdss.obj + >> putty.rsp
+	echo sshmd5.obj sshpubk.obj sshrand.obj sshrsa.obj + >> putty.rsp
+	echo sshsh512.obj sshsha.obj sshzlib.obj telnet.obj + >> putty.rsp
+	echo terminal.obj tree234.obj unicode.obj version.obj + >> putty.rsp
+	echo wcwidth.obj wildcard.obj wincfg.obj winctrls.obj + >> putty.rsp
+	echo windefs.obj windlg.obj window.obj winmisc.obj + >> putty.rsp
+	echo winnet.obj winstore.obj winutils.obj x11fwd.obj >> putty.rsp
 	echo putty.exe >> putty.rsp
 	echo nul,cw32 import32, >> putty.rsp
 	echo win_res.res >> putty.rsp
@@ -256,318 +256,338 @@ puttygen.rsp: $(MAKEFILE)
 puttytel.rsp: $(MAKEFILE)
 	echo c0w32 + > puttytel.rsp
 	echo be_nossh.obj cmdline.obj config.obj dialog.obj + >> puttytel.rsp
-	echo ldisc.obj ldiscucs.obj logging.obj misc.obj + >> puttytel.rsp
-	echo pproxy.obj printing.obj proxy.obj raw.obj + >> puttytel.rsp
-	echo rlogin.obj settings.obj sizetip.obj telnet.obj + >> puttytel.rsp
-	echo terminal.obj tree234.obj unicode.obj version.obj + >> puttytel.rsp
-	echo wcwidth.obj wincfg.obj winctrls.obj windefs.obj + >> puttytel.rsp
-	echo windlg.obj window.obj winmisc.obj winnet.obj + >> puttytel.rsp
-	echo winstore.obj winutils.obj >> puttytel.rsp
+	echo ldisc.obj ldiscucs.obj logging.obj minibidi.obj + >> puttytel.rsp
+	echo misc.obj pproxy.obj printing.obj proxy.obj + >> puttytel.rsp
+	echo raw.obj rlogin.obj settings.obj sizetip.obj + >> puttytel.rsp
+	echo telnet.obj terminal.obj tree234.obj unicode.obj + >> puttytel.rsp
+	echo version.obj wcwidth.obj wincfg.obj winctrls.obj + >> puttytel.rsp
+	echo windefs.obj windlg.obj window.obj winmisc.obj + >> puttytel.rsp
+	echo winnet.obj winstore.obj winutils.obj >> puttytel.rsp
 	echo puttytel.exe >> puttytel.rsp
 	echo nul,cw32 import32, >> puttytel.rsp
 	echo win_res.res >> puttytel.rsp
 
-be_all.obj: be_all.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_none.obj: be_none.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_nossh.obj: be_nossh.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-cmdgen.obj: cmdgen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-cmdline.obj: cmdline.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-config.obj: config.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-console.obj: console.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-dialog.obj: dialog.c putty.h dialog.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+be_all.obj: .\be_all.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_none.obj: .\be_none.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_nossh.obj: .\be_nossh.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+cmdgen.obj: .\cmdgen.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+cmdline.obj: .\cmdline.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+config.obj: .\config.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+console.obj: .\console.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+dialog.obj: .\dialog.c .\putty.h .\dialog.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 fromucs.obj: charset\fromucs.c charset\charset.h charset\internal.h
 gtkcols.obj: unix\gtkcols.c unix\gtkcols.h
-gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h putty.h storage.h \
-		dialog.h tree234.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
+gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h .\putty.h \
+		.\storage.h .\dialog.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
 gtkpanel.obj: unix\gtkpanel.c unix\gtkpanel.h
-import.obj: import.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-int64.obj: int64.c int64.h
-ldisc.obj: ldisc.c putty.h terminal.h ldisc.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ldiscucs.obj: ldiscucs.c putty.h terminal.h ldisc.h puttyps.h network.h \
-		misc.h tree234.h winstuff.h mac\macstuff.h unix\unix.h \
-		puttymem.h winhelp.h charset\charset.h
+import.obj: .\import.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+int64.obj: .\int64.c .\int64.h
+ldisc.obj: .\ldisc.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
+ldiscucs.obj: .\ldiscucs.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
 localenc.obj: charset\localenc.c charset\charset.h charset\internal.h
-logging.obj: logging.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mac.obj: mac\mac.c mac\macresid.h putty.h ssh.h terminal.h mac\mac.h \
-		puttyps.h network.h misc.h puttymem.h int64.h tree234.h \
-		charset\charset.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
+logging.obj: .\logging.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+mac.obj: mac\mac.c mac\macresid.h .\putty.h .\ssh.h .\terminal.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\tree234.h charset\charset.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 mac_res.res: mac\mac_res.r mac\macresid.h mac\version.r
-macabout.obj: mac\macabout.c putty.h mac\mac.h mac\macresid.h puttyps.h \
-		network.h misc.h charset\charset.h tree234.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macctrls.obj: mac\macctrls.c putty.h mac\mac.h mac\macresid.h dialog.h \
-		tree234.h puttyps.h network.h misc.h charset\charset.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macdlg.obj: mac\macdlg.c putty.h dialog.h mac\mac.h mac\macresid.h storage.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
+macabout.obj: mac\macabout.c .\putty.h mac\mac.h mac\macresid.h .\puttyps.h \
+		.\network.h .\misc.h charset\charset.h .\tree234.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\winhelp.h
+macctrls.obj: mac\macctrls.c .\putty.h mac\mac.h mac\macresid.h .\dialog.h \
+		.\tree234.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macdlg.obj: mac\macdlg.c .\putty.h .\dialog.h mac\mac.h mac\macresid.h \
+		.\storage.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
 macenc.obj: charset\macenc.c charset\charset.h charset\internal.h
-macevlog.obj: mac\macevlog.c putty.h mac\mac.h mac\macresid.h terminal.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macmisc.obj: mac\macmisc.c putty.h mac\mac.h puttyps.h network.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnet.obj: mac\macnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnoise.obj: mac\macnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-macpgen.obj: mac\macpgen.c mac\macpgrid.h putty.h ssh.h mac\mac.h puttyps.h \
-		network.h misc.h puttymem.h int64.h charset\charset.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h
+macevlog.obj: mac\macevlog.c .\putty.h mac\mac.h mac\macresid.h .\terminal.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macmisc.obj: mac\macmisc.c .\putty.h mac\mac.h .\puttyps.h .\network.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnet.obj: mac\macnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnoise.obj: mac\macnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+macpgen.obj: mac\macpgen.c mac\macpgrid.h .\putty.h .\ssh.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 macpgen.res: mac\macpgen.r mac\macpgrid.h mac\version.r
-macpgkey.obj: mac\macpgkey.c putty.h mac\mac.h mac\macpgrid.h ssh.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
-macstore.obj: mac\macstore.c putty.h storage.h mac\mac.h mac\macresid.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macterm.obj: mac\macterm.c mac\macresid.h putty.h charset\charset.h \
-		mac\mac.h terminal.h puttyps.h network.h misc.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macucs.obj: mac\macucs.c putty.h terminal.h misc.h mac\mac.h puttyps.h \
-		network.h tree234.h puttymem.h charset\charset.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
+macpgkey.obj: mac\macpgkey.c .\putty.h mac\mac.h mac\macpgrid.h .\ssh.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h
+macstore.obj: mac\macstore.c .\putty.h .\storage.h mac\mac.h mac\macresid.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macterm.obj: mac\macterm.c mac\macresid.h .\putty.h charset\charset.h \
+		mac\mac.h .\terminal.h .\puttyps.h .\network.h .\misc.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macucs.obj: mac\macucs.c .\putty.h .\terminal.h .\misc.h mac\mac.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\winhelp.h
 mimeenc.obj: charset\mimeenc.c charset\charset.h charset\internal.h
-misc.obj: misc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mtcpnet.obj: mac\mtcpnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-noise.obj: noise.c putty.h ssh.h storage.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-otnet.obj: mac\otnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-pageant.obj: pageant.c putty.h ssh.h misc.h tree234.h puttyps.h network.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
-pageant.res: pageant.rc pageant.ico pageants.ico
-pageantc.obj: pageantc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-plink.obj: plink.c putty.h storage.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-plink.res: plink.rc putty.ico
-portfwd.obj: portfwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-pproxy.obj: pproxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-printing.obj: printing.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-proxy.obj: proxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-psftp.obj: psftp.c putty.h psftp.h storage.h ssh.h sftp.h int64.h puttyps.h \
-		network.h misc.h puttymem.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-pterm.obj: unix\pterm.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ptermm.obj: unix\ptermm.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-pty.obj: unix\pty.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-puttygen.obj: puttygen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-puttygen.res: puttygen.rc puttygen.ico
-raw.obj: raw.c putty.h puttyps.h network.h misc.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h tree234.h winhelp.h charset\charset.h
-rlogin.obj: rlogin.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+minibidi.obj: .\minibidi.c .\minibidi.h
+misc.obj: .\misc.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+mtcpnet.obj: mac\mtcpnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+noise.obj: .\noise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+otnet.obj: mac\otnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
+pageant.obj: .\pageant.c .\putty.h .\ssh.h .\misc.h .\tree234.h .\puttyps.h \
+		.\network.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
+pageant.res: .\pageant.rc .\pageant.ico .\pageants.ico
+pageantc.obj: .\pageantc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+plink.obj: .\plink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+plink.res: .\plink.rc .\putty.ico
+portfwd.obj: .\portfwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+pproxy.obj: .\pproxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+printing.obj: .\printing.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+proxy.obj: .\proxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+psftp.obj: .\psftp.c .\putty.h .\psftp.h .\storage.h .\ssh.h .\sftp.h \
+		.\int64.h .\puttyps.h .\network.h .\misc.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+pterm.obj: unix\pterm.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+ptermm.obj: unix\ptermm.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+pty.obj: unix\pty.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+puttygen.obj: .\puttygen.c .\putty.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+puttygen.res: .\puttygen.rc .\puttygen.ico
+raw.obj: .\raw.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+rlogin.obj: .\rlogin.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 sbcs.obj: charset\sbcs.c charset\charset.h charset\internal.h
 sbcsdat.obj: charset\sbcsdat.c charset\charset.h charset\internal.h
-scp.obj: scp.c putty.h psftp.h ssh.h sftp.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-scp.res: scp.rc scp.ico
-settings.obj: settings.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-sftp.obj: sftp.c misc.h int64.h tree234.h sftp.h puttymem.h
+scp.obj: .\scp.c .\putty.h .\psftp.h .\ssh.h .\sftp.h .\storage.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+scp.res: .\scp.rc .\scp.ico
+settings.obj: .\settings.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+sftp.obj: .\sftp.c .\misc.h .\int64.h .\tree234.h .\sftp.h .\puttymem.h
 signal.obj: unix\signal.c
-sizetip.obj: sizetip.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+sizetip.obj: .\sizetip.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 slookup.obj: charset\slookup.c charset\charset.h charset\internal.h \
 		charset\enum.c charset\sbcsdat.c charset\utf8.c
-ssh.obj: ssh.c putty.h tree234.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h
-sshaes.obj: sshaes.c ssh.h puttymem.h network.h int64.h misc.h
-sshblowf.obj: sshblowf.c ssh.h puttymem.h network.h int64.h misc.h
-sshbn.obj: sshbn.c misc.h ssh.h puttymem.h network.h int64.h
-sshcrc.obj: sshcrc.c ssh.h puttymem.h network.h int64.h misc.h
-sshcrcda.obj: sshcrcda.c misc.h ssh.h puttymem.h network.h int64.h
-sshdes.obj: sshdes.c ssh.h puttymem.h network.h int64.h misc.h
-sshdh.obj: sshdh.c ssh.h puttymem.h network.h int64.h misc.h
-sshdss.obj: sshdss.c ssh.h misc.h puttymem.h network.h int64.h
-sshdssg.obj: sshdssg.c misc.h ssh.h puttymem.h network.h int64.h
-sshmd5.obj: sshmd5.c ssh.h puttymem.h network.h int64.h misc.h
-sshprime.obj: sshprime.c ssh.h puttymem.h network.h int64.h misc.h
-sshpubk.obj: sshpubk.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrand.obj: sshrand.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrsa.obj: sshrsa.c ssh.h misc.h puttymem.h network.h int64.h
-sshrsag.obj: sshrsag.c ssh.h puttymem.h network.h int64.h misc.h
-sshsh512.obj: sshsh512.c ssh.h puttymem.h network.h int64.h misc.h
-sshsha.obj: sshsha.c ssh.h puttymem.h network.h int64.h misc.h
-sshzlib.obj: sshzlib.c ssh.h puttymem.h network.h int64.h misc.h
-stricmp.obj: mac\stricmp.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-telnet.obj: telnet.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-terminal.obj: terminal.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-testback.obj: testback.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+ssh.obj: .\ssh.c .\putty.h .\tree234.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+sshaes.obj: .\sshaes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshblowf.obj: .\sshblowf.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshbn.obj: .\sshbn.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshcrc.obj: .\sshcrc.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshcrcda.obj: .\sshcrcda.c .\misc.h .\ssh.h .\puttymem.h .\network.h \
+		.\int64.h
+sshdes.obj: .\sshdes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdh.obj: .\sshdh.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdss.obj: .\sshdss.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshdssg.obj: .\sshdssg.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshmd5.obj: .\sshmd5.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshprime.obj: .\sshprime.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshpubk.obj: .\sshpubk.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrand.obj: .\sshrand.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrsa.obj: .\sshrsa.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshrsag.obj: .\sshrsag.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshsh512.obj: .\sshsh512.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshsha.obj: .\sshsha.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshzlib.obj: .\sshzlib.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+stricmp.obj: mac\stricmp.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+telnet.obj: .\telnet.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+terminal.obj: .\terminal.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+testback.obj: .\testback.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 toucs.obj: charset\toucs.c charset\charset.h charset\internal.h
-tree234.obj: tree234.c puttymem.h tree234.h
-unicode.obj: unicode.c putty.h terminal.h misc.h puttyps.h network.h \
-		tree234.h puttymem.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
+tree234.obj: .\tree234.c .\puttymem.h .\tree234.h
+unicode.obj: .\unicode.c .\putty.h .\terminal.h .\misc.h .\puttyps.h \
+		.\network.h .\tree234.h .\puttymem.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
 utf8.obj: charset\utf8.c charset\charset.h charset\internal.h
-ux_x11.obj: unix\ux_x11.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxagentc.obj: unix\uxagentc.c putty.h misc.h tree234.h puttymem.h puttyps.h \
-		network.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h
-uxcfg.obj: unix\uxcfg.c putty.h dialog.h storage.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		tree234.h winhelp.h charset\charset.h
-uxcons.obj: unix\uxcons.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-uxgen.obj: unix\uxgen.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxmisc.obj: unix\uxmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxnet.obj: unix\uxnet.c putty.h network.h tree234.h puttyps.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxnoise.obj: unix\uxnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-uxplink.obj: unix\uxplink.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxprint.obj: unix\uxprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxproxy.obj: unix\uxproxy.c tree234.h putty.h network.h proxy.h puttyps.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxputty.obj: unix\uxputty.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxsel.obj: unix\uxsel.c putty.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxsftp.obj: unix\uxsftp.c putty.h psftp.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxstore.obj: unix\uxstore.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxucs.obj: unix\uxucs.c putty.h charset\charset.h terminal.h misc.h \
-		puttyps.h network.h tree234.h puttymem.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
-version.obj: version.c
-vsnprint.obj: mac\vsnprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wcwidth.obj: wcwidth.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wildcard.obj: wildcard.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-win_res.res: win_res.rc win_res.h putty.ico puttycfg.ico
-wincfg.obj: wincfg.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winctrls.obj: winctrls.c putty.h misc.h dialog.h puttyps.h network.h \
-		puttymem.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-windefs.obj: windefs.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-windlg.obj: windlg.c putty.h ssh.h win_res.h storage.h dialog.h puttyps.h \
-		network.h misc.h puttymem.h int64.h winstuff.h \
-		mac\macstuff.h unix\unix.h tree234.h winhelp.h \
-		charset\charset.h
-window.obj: window.c putty.h terminal.h storage.h win_res.h puttyps.h \
-		network.h misc.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h charset\charset.h
-winmisc.obj: winmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winnet.obj: winnet.c putty.h network.h tree234.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-winsftp.obj: winsftp.c putty.h psftp.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winstore.obj: winstore.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winutils.obj: winutils.c misc.h puttymem.h
-x11fwd.obj: x11fwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
+ux_x11.obj: unix\ux_x11.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+uxagentc.obj: unix\uxagentc.c .\putty.h .\misc.h .\tree234.h .\puttymem.h \
+		.\puttyps.h .\network.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+uxcfg.obj: unix\uxcfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxcons.obj: unix\uxcons.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxgen.obj: unix\uxgen.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxmisc.obj: unix\uxmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxnet.obj: unix\uxnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxnoise.obj: unix\uxnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxplink.obj: unix\uxplink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxprint.obj: unix\uxprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxproxy.obj: unix\uxproxy.c .\tree234.h .\putty.h .\network.h .\proxy.h \
+		.\puttyps.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxputty.obj: unix\uxputty.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxsel.obj: unix\uxsel.c .\putty.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxsftp.obj: unix\uxsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxstore.obj: unix\uxstore.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxucs.obj: unix\uxucs.c .\putty.h charset\charset.h .\terminal.h .\misc.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\winhelp.h
+version.obj: .\version.c
+vsnprint.obj: mac\vsnprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wcwidth.obj: .\wcwidth.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wildcard.obj: .\wildcard.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+win_res.res: .\win_res.rc .\win_res.h .\putty.ico .\puttycfg.ico
+wincfg.obj: .\wincfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winctrls.obj: .\winctrls.c .\putty.h .\misc.h .\dialog.h .\puttyps.h \
+		.\network.h .\puttymem.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+windefs.obj: .\windefs.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+windlg.obj: .\windlg.c .\putty.h .\ssh.h .\win_res.h .\storage.h .\dialog.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+window.obj: .\window.c .\putty.h .\terminal.h .\storage.h .\win_res.h \
+		.\puttyps.h .\network.h .\misc.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h \
+		charset\charset.h
+winmisc.obj: .\winmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+winnet.obj: .\winnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+winsftp.obj: .\winsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winstore.obj: .\winstore.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winutils.obj: .\winutils.c .\misc.h .\puttymem.h
+x11fwd.obj: .\x11fwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
 xenc.obj: charset\xenc.c charset\charset.h charset\internal.h
-xkeysym.obj: unix\xkeysym.c misc.h puttymem.h
+xkeysym.obj: unix\xkeysym.c .\misc.h .\puttymem.h
 
-version.o: FORCE
-# Hack to force version.o to be rebuilt always
+version.obj: FORCE
 FORCE:
 	bcc32 $(FWHACK) $(VER) $(CFLAGS) /c version.c
 

+ 372 - 351
putty/MAKEFILE.CYG

@@ -1,4 +1,4 @@
-# Makefile for PuTTY under cygwin.
+# Makefile for putty under cygwin.
 #
 # This file was created by `mkfiles.pl' from the `Recipe' file.
 # DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.
@@ -88,7 +88,7 @@ RC = $(TOOLPATH)windres
 # RCINC = --include-dir c:\cygwin\include\
 
 CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT \
-		-D_NO_OLDNAMES -DNO_MULTIMON -I.
+		-D_NO_OLDNAMES -DNO_MULTIMON -I./ -Icharset/ -Iunix/ -Imac/
 LDFLAGS = -mno-cygwin -s
 RCFLAGS = $(RCINC) --define WIN32=1 --define _WIN32=1 --define WINVER=0x0400 \
 		--define MINGW32_FIX=1
@@ -107,11 +107,12 @@ all: pageant.exe plink.exe pscp.exe psftp.exe putty.exe puttygen.exe \
 pageant.exe: misc.o pageant.o pageant.res.o pageantc.o sshaes.o sshbn.o \
 		sshdes.o sshdss.o sshmd5.o sshpubk.o sshrsa.o sshsh512.o \
 		sshsha.o tree234.o version.o winmisc.o winutils.o
-	$(CC) -mwindows $(LDFLAGS) -o $@ misc.o pageant.o pageant.res.o \
-		pageantc.o sshaes.o sshbn.o sshdes.o sshdss.o sshmd5.o \
-		sshpubk.o sshrsa.o sshsh512.o sshsha.o tree234.o version.o \
-		winmisc.o winutils.o -ladvapi32 -lcomctl32 -lcomdlg32 \
-		-lgdi32 -limm32 -lshell32 -luser32 -lwinmm -lwinspool
+	$(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,pageant.map misc.o \
+		pageant.o pageant.res.o pageantc.o sshaes.o sshbn.o sshdes.o \
+		sshdss.o sshmd5.o sshpubk.o sshrsa.o sshsh512.o sshsha.o \
+		tree234.o version.o winmisc.o winutils.o -ladvapi32 \
+		-lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 \
+		-lwinmm -lwinspool
 
 plink.exe: be_all.o cmdline.o console.o ldisc.o logging.o misc.o noise.o \
 		pageantc.o plink.o plink.res.o portfwd.o pproxy.o proxy.o \
@@ -120,15 +121,16 @@ plink.exe: be_all.o cmdline.o console.o ldisc.o logging.o misc.o noise.o \
 		sshpubk.o sshrand.o sshrsa.o sshsh512.o sshsha.o sshzlib.o \
 		telnet.o tree234.o version.o wildcard.o windefs.o winmisc.o \
 		winnet.o winstore.o x11fwd.o
-	$(CC) $(LDFLAGS) -o $@ be_all.o cmdline.o console.o ldisc.o \
-		logging.o misc.o noise.o pageantc.o plink.o plink.res.o \
-		portfwd.o pproxy.o proxy.o raw.o rlogin.o settings.o ssh.o \
-		sshaes.o sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o \
-		sshdh.o sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o \
-		sshsh512.o sshsha.o sshzlib.o telnet.o tree234.o version.o \
-		wildcard.o windefs.o winmisc.o winnet.o winstore.o x11fwd.o \
-		-ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 \
-		-luser32 -lwinmm -lwinspool
+	$(CC) $(LDFLAGS) -o $@ -Wl,-Map,plink.map be_all.o cmdline.o \
+		console.o ldisc.o logging.o misc.o noise.o pageantc.o \
+		plink.o plink.res.o portfwd.o pproxy.o proxy.o raw.o \
+		rlogin.o settings.o ssh.o sshaes.o sshblowf.o sshbn.o \
+		sshcrc.o sshcrcda.o sshdes.o sshdh.o sshdss.o sshmd5.o \
+		sshpubk.o sshrand.o sshrsa.o sshsh512.o sshsha.o sshzlib.o \
+		telnet.o tree234.o version.o wildcard.o windefs.o winmisc.o \
+		winnet.o winstore.o x11fwd.o -ladvapi32 -lcomctl32 \
+		-lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 -lwinmm \
+		-lwinspool
 
 pscp.exe: be_none.o cmdline.o console.o int64.o logging.o misc.o noise.o \
 		pageantc.o portfwd.o pproxy.o proxy.o scp.o scp.res.o \
@@ -137,15 +139,15 @@ pscp.exe: be_none.o cmdline.o console.o int64.o logging.o misc.o noise.o \
 		sshrand.o sshrsa.o sshsh512.o sshsha.o sshzlib.o tree234.o \
 		version.o wildcard.o windefs.o winmisc.o winnet.o winsftp.o \
 		winstore.o x11fwd.o
-	$(CC) $(LDFLAGS) -o $@ be_none.o cmdline.o console.o int64.o \
-		logging.o misc.o noise.o pageantc.o portfwd.o pproxy.o \
-		proxy.o scp.o scp.res.o settings.o sftp.o ssh.o sshaes.o \
-		sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o sshdh.o \
-		sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o sshsh512.o \
-		sshsha.o sshzlib.o tree234.o version.o wildcard.o windefs.o \
-		winmisc.o winnet.o winsftp.o winstore.o x11fwd.o -ladvapi32 \
-		-lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 \
-		-lwinmm -lwinspool
+	$(CC) $(LDFLAGS) -o $@ -Wl,-Map,pscp.map be_none.o cmdline.o \
+		console.o int64.o logging.o misc.o noise.o pageantc.o \
+		portfwd.o pproxy.o proxy.o scp.o scp.res.o settings.o sftp.o \
+		ssh.o sshaes.o sshblowf.o sshbn.o sshcrc.o sshcrcda.o \
+		sshdes.o sshdh.o sshdss.o sshmd5.o sshpubk.o sshrand.o \
+		sshrsa.o sshsh512.o sshsha.o sshzlib.o tree234.o version.o \
+		wildcard.o windefs.o winmisc.o winnet.o winsftp.o winstore.o \
+		x11fwd.o -ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 \
+		-lshell32 -luser32 -lwinmm -lwinspool
 
 psftp.exe: be_none.o cmdline.o console.o int64.o logging.o misc.o noise.o \
 		pageantc.o portfwd.o pproxy.o proxy.o psftp.o scp.res.o \
@@ -154,365 +156,384 @@ psftp.exe: be_none.o cmdline.o console.o int64.o logging.o misc.o noise.o \
 		sshrand.o sshrsa.o sshsh512.o sshsha.o sshzlib.o tree234.o \
 		version.o wildcard.o windefs.o winmisc.o winnet.o winsftp.o \
 		winstore.o x11fwd.o
-	$(CC) $(LDFLAGS) -o $@ be_none.o cmdline.o console.o int64.o \
-		logging.o misc.o noise.o pageantc.o portfwd.o pproxy.o \
-		proxy.o psftp.o scp.res.o settings.o sftp.o ssh.o sshaes.o \
-		sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o sshdh.o \
-		sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o sshsh512.o \
-		sshsha.o sshzlib.o tree234.o version.o wildcard.o windefs.o \
-		winmisc.o winnet.o winsftp.o winstore.o x11fwd.o -ladvapi32 \
-		-lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 \
-		-lwinmm -lwinspool
+	$(CC) $(LDFLAGS) -o $@ -Wl,-Map,psftp.map be_none.o cmdline.o \
+		console.o int64.o logging.o misc.o noise.o pageantc.o \
+		portfwd.o pproxy.o proxy.o psftp.o scp.res.o settings.o \
+		sftp.o ssh.o sshaes.o sshblowf.o sshbn.o sshcrc.o sshcrcda.o \
+		sshdes.o sshdh.o sshdss.o sshmd5.o sshpubk.o sshrand.o \
+		sshrsa.o sshsh512.o sshsha.o sshzlib.o tree234.o version.o \
+		wildcard.o windefs.o winmisc.o winnet.o winsftp.o winstore.o \
+		x11fwd.o -ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 \
+		-lshell32 -luser32 -lwinmm -lwinspool
 
 putty.exe: be_all.o cmdline.o config.o dialog.o ldisc.o ldiscucs.o logging.o \
-		misc.o noise.o pageantc.o portfwd.o pproxy.o printing.o \
-		proxy.o raw.o rlogin.o settings.o sizetip.o ssh.o sshaes.o \
-		sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o sshdh.o \
-		sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o sshsh512.o \
-		sshsha.o sshzlib.o telnet.o terminal.o tree234.o unicode.o \
-		version.o wcwidth.o wildcard.o win_res.res.o wincfg.o \
-		winctrls.o windefs.o windlg.o window.o winmisc.o winnet.o \
-		winstore.o winutils.o x11fwd.o
-	$(CC) -mwindows $(LDFLAGS) -o $@ be_all.o cmdline.o config.o \
-		dialog.o ldisc.o ldiscucs.o logging.o misc.o noise.o \
-		pageantc.o portfwd.o pproxy.o printing.o proxy.o raw.o \
-		rlogin.o settings.o sizetip.o ssh.o sshaes.o sshblowf.o \
-		sshbn.o sshcrc.o sshcrcda.o sshdes.o sshdh.o sshdss.o \
-		sshmd5.o sshpubk.o sshrand.o sshrsa.o sshsh512.o sshsha.o \
-		sshzlib.o telnet.o terminal.o tree234.o unicode.o version.o \
-		wcwidth.o wildcard.o win_res.res.o wincfg.o winctrls.o \
-		windefs.o windlg.o window.o winmisc.o winnet.o winstore.o \
-		winutils.o x11fwd.o -ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 \
-		-limm32 -lshell32 -luser32 -lwinmm -lwinspool
+		minibidi.o misc.o noise.o pageantc.o portfwd.o pproxy.o \
+		printing.o proxy.o raw.o rlogin.o settings.o sizetip.o ssh.o \
+		sshaes.o sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o \
+		sshdh.o sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o \
+		sshsh512.o sshsha.o sshzlib.o telnet.o terminal.o tree234.o \
+		unicode.o version.o wcwidth.o wildcard.o win_res.res.o \
+		wincfg.o winctrls.o windefs.o windlg.o window.o winmisc.o \
+		winnet.o winstore.o winutils.o x11fwd.o
+	$(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,putty.map be_all.o \
+		cmdline.o config.o dialog.o ldisc.o ldiscucs.o logging.o \
+		minibidi.o misc.o noise.o pageantc.o portfwd.o pproxy.o \
+		printing.o proxy.o raw.o rlogin.o settings.o sizetip.o ssh.o \
+		sshaes.o sshblowf.o sshbn.o sshcrc.o sshcrcda.o sshdes.o \
+		sshdh.o sshdss.o sshmd5.o sshpubk.o sshrand.o sshrsa.o \
+		sshsh512.o sshsha.o sshzlib.o telnet.o terminal.o tree234.o \
+		unicode.o version.o wcwidth.o wildcard.o win_res.res.o \
+		wincfg.o winctrls.o windefs.o windlg.o window.o winmisc.o \
+		winnet.o winstore.o winutils.o x11fwd.o -ladvapi32 \
+		-lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 \
+		-lwinmm -lwinspool
 
 puttygen.exe: import.o misc.o noise.o puttygen.o puttygen.res.o sshaes.o \
 		sshbn.o sshdes.o sshdss.o sshdssg.o sshmd5.o sshprime.o \
 		sshpubk.o sshrand.o sshrsa.o sshrsag.o sshsh512.o sshsha.o \
 		tree234.o version.o winctrls.o winmisc.o winstore.o \
 		winutils.o
-	$(CC) -mwindows $(LDFLAGS) -o $@ import.o misc.o noise.o puttygen.o \
-		puttygen.res.o sshaes.o sshbn.o sshdes.o sshdss.o sshdssg.o \
-		sshmd5.o sshprime.o sshpubk.o sshrand.o sshrsa.o sshrsag.o \
-		sshsh512.o sshsha.o tree234.o version.o winctrls.o winmisc.o \
-		winstore.o winutils.o -ladvapi32 -lcomctl32 -lcomdlg32 \
-		-lgdi32 -limm32 -lshell32 -luser32 -lwinmm -lwinspool
+	$(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,puttygen.map import.o \
+		misc.o noise.o puttygen.o puttygen.res.o sshaes.o sshbn.o \
+		sshdes.o sshdss.o sshdssg.o sshmd5.o sshprime.o sshpubk.o \
+		sshrand.o sshrsa.o sshrsag.o sshsh512.o sshsha.o tree234.o \
+		version.o winctrls.o winmisc.o winstore.o winutils.o \
+		-ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 \
+		-luser32 -lwinmm -lwinspool
 
 puttytel.exe: be_nossh.o cmdline.o config.o dialog.o ldisc.o ldiscucs.o \
-		logging.o misc.o pproxy.o printing.o proxy.o raw.o rlogin.o \
+		logging.o minibidi.o misc.o pproxy.o printing.o proxy.o \
+		raw.o rlogin.o settings.o sizetip.o telnet.o terminal.o \
+		tree234.o unicode.o version.o wcwidth.o win_res.res.o \
+		wincfg.o winctrls.o windefs.o windlg.o window.o winmisc.o \
+		winnet.o winstore.o winutils.o
+	$(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,puttytel.map be_nossh.o \
+		cmdline.o config.o dialog.o ldisc.o ldiscucs.o logging.o \
+		minibidi.o misc.o pproxy.o printing.o proxy.o raw.o rlogin.o \
 		settings.o sizetip.o telnet.o terminal.o tree234.o unicode.o \
 		version.o wcwidth.o win_res.res.o wincfg.o winctrls.o \
 		windefs.o windlg.o window.o winmisc.o winnet.o winstore.o \
-		winutils.o
-	$(CC) -mwindows $(LDFLAGS) -o $@ be_nossh.o cmdline.o config.o \
-		dialog.o ldisc.o ldiscucs.o logging.o misc.o pproxy.o \
-		printing.o proxy.o raw.o rlogin.o settings.o sizetip.o \
-		telnet.o terminal.o tree234.o unicode.o version.o wcwidth.o \
-		win_res.res.o wincfg.o winctrls.o windefs.o windlg.o \
-		window.o winmisc.o winnet.o winstore.o winutils.o -ladvapi32 \
-		-lcomctl32 -lcomdlg32 -lgdi32 -limm32 -lshell32 -luser32 \
-		-lwinmm -lwinspool
+		winutils.o -ladvapi32 -lcomctl32 -lcomdlg32 -lgdi32 -limm32 \
+		-lshell32 -luser32 -lwinmm -lwinspool
 
-be_all.o: be_all.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-be_none.o: be_none.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-be_nossh.o: be_nossh.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-cmdgen.o: cmdgen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-cmdline.o: cmdline.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-config.o: config.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-console.o: console.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac/macstuff.h unix/unix.h \
-		tree234.h winhelp.h charset/charset.h
-dialog.o: dialog.c putty.h dialog.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
+be_all.o: ./be_all.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
+be_none.o: ./be_none.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+be_nossh.o: ./be_nossh.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+cmdgen.o: ./cmdgen.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+cmdline.o: ./cmdline.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+config.o: ./config.c ./putty.h ./dialog.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+console.o: ./console.c ./putty.h ./storage.h ./ssh.h ./puttyps.h ./network.h \
+		./misc.h ./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+dialog.o: ./dialog.c ./putty.h ./dialog.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
 fromucs.o: charset/fromucs.c charset/charset.h charset/internal.h
 gtkcols.o: unix/gtkcols.c unix/gtkcols.h
-gtkdlg.o: unix/gtkdlg.c unix/gtkcols.h unix/gtkpanel.h putty.h storage.h \
-		dialog.h tree234.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h winhelp.h \
-		charset/charset.h
+gtkdlg.o: unix/gtkdlg.c unix/gtkcols.h unix/gtkpanel.h ./putty.h ./storage.h \
+		./dialog.h ./tree234.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./winhelp.h charset/charset.h
 gtkpanel.o: unix/gtkpanel.c unix/gtkpanel.h
-import.o: import.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-int64.o: int64.c int64.h
-ldisc.o: ldisc.c putty.h terminal.h ldisc.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-ldiscucs.o: ldiscucs.c putty.h terminal.h ldisc.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
+import.o: ./import.c ./putty.h ./ssh.h ./misc.h ./puttyps.h ./network.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+int64.o: ./int64.c ./int64.h
+ldisc.o: ./ldisc.c ./putty.h ./terminal.h ./ldisc.h ./puttyps.h ./network.h \
+		./misc.h ./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+ldiscucs.o: ./ldiscucs.c ./putty.h ./terminal.h ./ldisc.h ./puttyps.h \
+		./network.h ./misc.h ./tree234.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./puttymem.h ./winhelp.h charset/charset.h
 localenc.o: charset/localenc.c charset/charset.h charset/internal.h
-logging.o: logging.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-mac.o: mac/mac.c mac/macresid.h putty.h ssh.h terminal.h mac/mac.h puttyps.h \
-		network.h misc.h puttymem.h int64.h tree234.h \
-		charset/charset.h winstuff.h mac/macstuff.h unix/unix.h \
-		winhelp.h
+logging.o: ./logging.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+mac.o: mac/mac.c mac/macresid.h ./putty.h ./ssh.h ./terminal.h mac/mac.h \
+		./puttyps.h ./network.h ./misc.h ./puttymem.h ./int64.h \
+		./tree234.h charset/charset.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./winhelp.h
 mac_res.res.o: mac/mac_res.r mac/macresid.h mac/version.r
-macabout.o: mac/macabout.c putty.h mac/mac.h mac/macresid.h puttyps.h \
-		network.h misc.h charset/charset.h tree234.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h winhelp.h
-macctrls.o: mac/macctrls.c putty.h mac/mac.h mac/macresid.h dialog.h \
-		tree234.h puttyps.h network.h misc.h charset/charset.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h
-macdlg.o: mac/macdlg.c putty.h dialog.h mac/mac.h mac/macresid.h storage.h \
-		puttyps.h network.h misc.h charset/charset.h tree234.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h
+macabout.o: mac/macabout.c ./putty.h mac/mac.h mac/macresid.h ./puttyps.h \
+		./network.h ./misc.h charset/charset.h ./tree234.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./winhelp.h
+macctrls.o: mac/macctrls.c ./putty.h mac/mac.h mac/macresid.h ./dialog.h \
+		./tree234.h ./puttyps.h ./network.h ./misc.h \
+		charset/charset.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h
+macdlg.o: mac/macdlg.c ./putty.h ./dialog.h mac/mac.h mac/macresid.h \
+		./storage.h ./puttyps.h ./network.h ./misc.h \
+		charset/charset.h ./tree234.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./puttymem.h ./winhelp.h
 macenc.o: charset/macenc.c charset/charset.h charset/internal.h
-macevlog.o: mac/macevlog.c putty.h mac/mac.h mac/macresid.h terminal.h \
-		puttyps.h network.h misc.h charset/charset.h tree234.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h
-macmisc.o: mac/macmisc.c putty.h mac/mac.h puttyps.h network.h misc.h \
-		charset/charset.h tree234.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h winhelp.h
-macnet.o: mac/macnet.c putty.h network.h mac/mac.h puttyps.h misc.h \
-		charset/charset.h tree234.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h winhelp.h
-macnoise.o: mac/macnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac/macstuff.h \
-		unix/unix.h tree234.h winhelp.h charset/charset.h
-macpgen.o: mac/macpgen.c mac/macpgrid.h putty.h ssh.h mac/mac.h puttyps.h \
-		network.h misc.h puttymem.h int64.h charset/charset.h \
-		tree234.h winstuff.h mac/macstuff.h unix/unix.h winhelp.h
+macevlog.o: mac/macevlog.c ./putty.h mac/mac.h mac/macresid.h ./terminal.h \
+		./puttyps.h ./network.h ./misc.h charset/charset.h \
+		./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h
+macmisc.o: mac/macmisc.c ./putty.h mac/mac.h ./puttyps.h ./network.h \
+		./misc.h charset/charset.h ./tree234.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./winhelp.h
+macnet.o: mac/macnet.c ./putty.h ./network.h mac/mac.h ./puttyps.h ./misc.h \
+		charset/charset.h ./tree234.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./puttymem.h ./winhelp.h
+macnoise.o: mac/macnoise.c ./putty.h ./ssh.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./tree234.h ./winhelp.h \
+		charset/charset.h
+macpgen.o: mac/macpgen.c mac/macpgrid.h ./putty.h ./ssh.h mac/mac.h \
+		./puttyps.h ./network.h ./misc.h ./puttymem.h ./int64.h \
+		charset/charset.h ./tree234.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./winhelp.h
 macpgen.res.o: mac/macpgen.r mac/macpgrid.h mac/version.r
-macpgkey.o: mac/macpgkey.c putty.h mac/mac.h mac/macpgrid.h ssh.h puttyps.h \
-		network.h misc.h charset/charset.h tree234.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h winhelp.h
-macstore.o: mac/macstore.c putty.h storage.h mac/mac.h mac/macresid.h \
-		puttyps.h network.h misc.h charset/charset.h tree234.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h
-macterm.o: mac/macterm.c mac/macresid.h putty.h charset/charset.h mac/mac.h \
-		terminal.h puttyps.h network.h misc.h tree234.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h winhelp.h
-macucs.o: mac/macucs.c putty.h terminal.h misc.h mac/mac.h puttyps.h \
-		network.h tree234.h puttymem.h charset/charset.h winstuff.h \
-		mac/macstuff.h unix/unix.h winhelp.h
+macpgkey.o: mac/macpgkey.c ./putty.h mac/mac.h mac/macpgrid.h ./ssh.h \
+		./puttyps.h ./network.h ./misc.h charset/charset.h \
+		./tree234.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./winhelp.h
+macstore.o: mac/macstore.c ./putty.h ./storage.h mac/mac.h mac/macresid.h \
+		./puttyps.h ./network.h ./misc.h charset/charset.h \
+		./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h
+macterm.o: mac/macterm.c mac/macresid.h ./putty.h charset/charset.h \
+		mac/mac.h ./terminal.h ./puttyps.h ./network.h ./misc.h \
+		./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h
+macucs.o: mac/macucs.c ./putty.h ./terminal.h ./misc.h mac/mac.h ./puttyps.h \
+		./network.h ./tree234.h ./puttymem.h charset/charset.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./winhelp.h
 mimeenc.o: charset/mimeenc.c charset/charset.h charset/internal.h
-misc.o: misc.c putty.h puttyps.h network.h misc.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h tree234.h winhelp.h charset/charset.h
-mtcpnet.o: mac/mtcpnet.c putty.h network.h mac/mac.h puttyps.h misc.h \
-		charset/charset.h tree234.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h winhelp.h
-noise.o: noise.c putty.h ssh.h storage.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac/macstuff.h unix/unix.h \
-		tree234.h winhelp.h charset/charset.h
-otnet.o: mac/otnet.c putty.h network.h mac/mac.h puttyps.h misc.h \
-		charset/charset.h tree234.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h winhelp.h
-pageant.o: pageant.c putty.h ssh.h misc.h tree234.h puttyps.h network.h \
-		puttymem.h int64.h winstuff.h mac/macstuff.h unix/unix.h \
-		winhelp.h charset/charset.h
-pageant.res.o: pageant.rc pageant.ico pageants.ico
-pageantc.o: pageantc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-plink.o: plink.c putty.h storage.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h \
-		charset/charset.h
-plink.res.o: plink.rc putty.ico
-portfwd.o: portfwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-pproxy.o: pproxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-printing.o: printing.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-proxy.o: proxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-psftp.o: psftp.c putty.h psftp.h storage.h ssh.h sftp.h int64.h puttyps.h \
-		network.h misc.h puttymem.h winstuff.h mac/macstuff.h \
-		unix/unix.h tree234.h winhelp.h charset/charset.h
-pterm.o: unix/pterm.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-ptermm.o: unix/ptermm.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-pty.o: unix/pty.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-puttygen.o: puttygen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-puttygen.res.o: puttygen.rc puttygen.ico
-raw.o: raw.c putty.h puttyps.h network.h misc.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h tree234.h winhelp.h charset/charset.h
-rlogin.o: rlogin.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
+minibidi.o: ./minibidi.c ./minibidi.h
+misc.o: ./misc.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
+mtcpnet.o: mac/mtcpnet.c ./putty.h ./network.h mac/mac.h ./puttyps.h \
+		./misc.h charset/charset.h ./tree234.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./winhelp.h
+noise.o: ./noise.c ./putty.h ./ssh.h ./storage.h ./puttyps.h ./network.h \
+		./misc.h ./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+otnet.o: mac/otnet.c ./putty.h ./network.h mac/mac.h ./puttyps.h ./misc.h \
+		charset/charset.h ./tree234.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./puttymem.h ./winhelp.h
+pageant.o: ./pageant.c ./putty.h ./ssh.h ./misc.h ./tree234.h ./puttyps.h \
+		./network.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./winhelp.h charset/charset.h
+pageant.res.o: ./pageant.rc ./pageant.ico ./pageants.ico
+pageantc.o: ./pageantc.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+plink.o: ./plink.c ./putty.h ./storage.h ./tree234.h ./puttyps.h ./network.h \
+		./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+plink.res.o: ./plink.rc ./putty.ico
+portfwd.o: ./portfwd.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+pproxy.o: ./pproxy.c ./putty.h ./network.h ./proxy.h ./puttyps.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+printing.o: ./printing.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+proxy.o: ./proxy.c ./putty.h ./network.h ./proxy.h ./puttyps.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+psftp.o: ./psftp.c ./putty.h ./psftp.h ./storage.h ./ssh.h ./sftp.h \
+		./int64.h ./puttyps.h ./network.h ./misc.h ./puttymem.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./tree234.h \
+		./winhelp.h charset/charset.h
+pterm.o: unix/pterm.c ./putty.h ./terminal.h ./puttyps.h ./network.h \
+		./misc.h ./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+ptermm.o: unix/ptermm.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+pty.o: unix/pty.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
+puttygen.o: ./puttygen.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+puttygen.res.o: ./puttygen.rc ./puttygen.ico
+raw.o: ./raw.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
+rlogin.o: ./rlogin.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
 sbcs.o: charset/sbcs.c charset/charset.h charset/internal.h
 sbcsdat.o: charset/sbcsdat.c charset/charset.h charset/internal.h
-scp.o: scp.c putty.h psftp.h ssh.h sftp.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac/macstuff.h \
-		unix/unix.h tree234.h winhelp.h charset/charset.h
-scp.res.o: scp.rc scp.ico
-settings.o: settings.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-sftp.o: sftp.c misc.h int64.h tree234.h sftp.h puttymem.h
+scp.o: ./scp.c ./putty.h ./psftp.h ./ssh.h ./sftp.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./tree234.h ./winhelp.h \
+		charset/charset.h
+scp.res.o: ./scp.rc ./scp.ico
+settings.o: ./settings.c ./putty.h ./storage.h ./puttyps.h ./network.h \
+		./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+sftp.o: ./sftp.c ./misc.h ./int64.h ./tree234.h ./sftp.h ./puttymem.h
 signal.o: unix/signal.c
-sizetip.o: sizetip.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
+sizetip.o: ./sizetip.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
 slookup.o: charset/slookup.c charset/charset.h charset/internal.h \
 		charset/enum.c charset/sbcsdat.c charset/utf8.c
-ssh.o: ssh.c putty.h tree234.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h winhelp.h \
-		charset/charset.h
-sshaes.o: sshaes.c ssh.h puttymem.h network.h int64.h misc.h
-sshblowf.o: sshblowf.c ssh.h puttymem.h network.h int64.h misc.h
-sshbn.o: sshbn.c misc.h ssh.h puttymem.h network.h int64.h
-sshcrc.o: sshcrc.c ssh.h puttymem.h network.h int64.h misc.h
-sshcrcda.o: sshcrcda.c misc.h ssh.h puttymem.h network.h int64.h
-sshdes.o: sshdes.c ssh.h puttymem.h network.h int64.h misc.h
-sshdh.o: sshdh.c ssh.h puttymem.h network.h int64.h misc.h
-sshdss.o: sshdss.c ssh.h misc.h puttymem.h network.h int64.h
-sshdssg.o: sshdssg.c misc.h ssh.h puttymem.h network.h int64.h
-sshmd5.o: sshmd5.c ssh.h puttymem.h network.h int64.h misc.h
-sshprime.o: sshprime.c ssh.h puttymem.h network.h int64.h misc.h
-sshpubk.o: sshpubk.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-sshrand.o: sshrand.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-sshrsa.o: sshrsa.c ssh.h misc.h puttymem.h network.h int64.h
-sshrsag.o: sshrsag.c ssh.h puttymem.h network.h int64.h misc.h
-sshsh512.o: sshsh512.c ssh.h puttymem.h network.h int64.h misc.h
-sshsha.o: sshsha.c ssh.h puttymem.h network.h int64.h misc.h
-sshzlib.o: sshzlib.c ssh.h puttymem.h network.h int64.h misc.h
-stricmp.o: mac/stricmp.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-telnet.o: telnet.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-terminal.o: terminal.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-testback.o: testback.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
+ssh.o: ./ssh.c ./putty.h ./tree234.h ./ssh.h ./puttyps.h ./network.h \
+		./misc.h ./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./winhelp.h charset/charset.h
+sshaes.o: ./sshaes.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshblowf.o: ./sshblowf.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshbn.o: ./sshbn.c ./misc.h ./ssh.h ./puttymem.h ./network.h ./int64.h
+sshcrc.o: ./sshcrc.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshcrcda.o: ./sshcrcda.c ./misc.h ./ssh.h ./puttymem.h ./network.h ./int64.h
+sshdes.o: ./sshdes.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshdh.o: ./sshdh.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshdss.o: ./sshdss.c ./ssh.h ./misc.h ./puttymem.h ./network.h ./int64.h
+sshdssg.o: ./sshdssg.c ./misc.h ./ssh.h ./puttymem.h ./network.h ./int64.h
+sshmd5.o: ./sshmd5.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshprime.o: ./sshprime.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshpubk.o: ./sshpubk.c ./putty.h ./ssh.h ./misc.h ./puttyps.h ./network.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+sshrand.o: ./sshrand.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+sshrsa.o: ./sshrsa.c ./ssh.h ./misc.h ./puttymem.h ./network.h ./int64.h
+sshrsag.o: ./sshrsag.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshsh512.o: ./sshsh512.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshsha.o: ./sshsha.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+sshzlib.o: ./sshzlib.c ./ssh.h ./puttymem.h ./network.h ./int64.h ./misc.h
+stricmp.o: mac/stricmp.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+telnet.o: ./telnet.c ./putty.h ./puttyps.h ./network.h ./misc.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./tree234.h \
+		./winhelp.h charset/charset.h
+terminal.o: ./terminal.c ./putty.h ./terminal.h ./puttyps.h ./network.h \
+		./misc.h ./tree234.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+testback.o: ./testback.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
 toucs.o: charset/toucs.c charset/charset.h charset/internal.h
-tree234.o: tree234.c puttymem.h tree234.h
-unicode.o: unicode.c putty.h terminal.h misc.h puttyps.h network.h tree234.h \
-		puttymem.h winstuff.h mac/macstuff.h unix/unix.h winhelp.h \
-		charset/charset.h
+tree234.o: ./tree234.c ./puttymem.h ./tree234.h
+unicode.o: ./unicode.c ./putty.h ./terminal.h ./misc.h ./puttyps.h \
+		./network.h ./tree234.h ./puttymem.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./winhelp.h charset/charset.h
 utf8.o: charset/utf8.c charset/charset.h charset/internal.h
-ux_x11.o: unix/ux_x11.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-uxagentc.o: unix/uxagentc.c putty.h misc.h tree234.h puttymem.h puttyps.h \
-		network.h winstuff.h mac/macstuff.h unix/unix.h winhelp.h \
-		charset/charset.h
-uxcfg.o: unix/uxcfg.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-uxcons.o: unix/uxcons.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac/macstuff.h unix/unix.h \
-		tree234.h winhelp.h charset/charset.h
-uxgen.o: unix/uxgen.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-uxmisc.o: unix/uxmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-uxnet.o: unix/uxnet.c putty.h network.h tree234.h puttyps.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h \
-		charset/charset.h
-uxnoise.o: unix/uxnoise.c putty.h ssh.h storage.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac/macstuff.h unix/unix.h \
-		tree234.h winhelp.h charset/charset.h
-uxplink.o: unix/uxplink.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-uxprint.o: unix/uxprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-uxproxy.o: unix/uxproxy.c tree234.h putty.h network.h proxy.h puttyps.h \
-		misc.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-uxputty.o: unix/uxputty.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-uxsel.o: unix/uxsel.c putty.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h winhelp.h \
-		charset/charset.h
-uxsftp.o: unix/uxsftp.c putty.h psftp.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-uxstore.o: unix/uxstore.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac/macstuff.h unix/unix.h puttymem.h \
-		winhelp.h charset/charset.h
-uxucs.o: unix/uxucs.c putty.h charset/charset.h terminal.h misc.h puttyps.h \
-		network.h tree234.h puttymem.h winstuff.h mac/macstuff.h \
-		unix/unix.h winhelp.h
-version.o: version.c
-vsnprint.o: mac/vsnprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-wcwidth.o: wcwidth.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-wildcard.o: wildcard.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-win_res.res.o: win_res.rc win_res.h putty.ico puttycfg.ico
-wincfg.o: wincfg.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-winctrls.o: winctrls.c putty.h misc.h dialog.h puttyps.h network.h \
-		puttymem.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
-windefs.o: windefs.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-windlg.o: windlg.c putty.h ssh.h win_res.h storage.h dialog.h puttyps.h \
-		network.h misc.h puttymem.h int64.h winstuff.h \
-		mac/macstuff.h unix/unix.h tree234.h winhelp.h \
-		charset/charset.h
-window.o: window.c putty.h terminal.h storage.h win_res.h puttyps.h \
-		network.h misc.h tree234.h winstuff.h mac/macstuff.h \
-		unix/unix.h puttymem.h winhelp.h charset/charset.h
-winmisc.o: winmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-winnet.o: winnet.c putty.h network.h tree234.h puttyps.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h winhelp.h \
-		charset/charset.h
-winsftp.o: winsftp.c putty.h psftp.h puttyps.h network.h misc.h winstuff.h \
-		mac/macstuff.h unix/unix.h puttymem.h tree234.h winhelp.h \
-		charset/charset.h
-winstore.o: winstore.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac/macstuff.h unix/unix.h puttymem.h tree234.h \
-		winhelp.h charset/charset.h
-winutils.o: winutils.c misc.h puttymem.h
-x11fwd.o: x11fwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac/macstuff.h unix/unix.h tree234.h \
-		winhelp.h charset/charset.h
+ux_x11.o: unix/ux_x11.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+uxagentc.o: unix/uxagentc.c ./putty.h ./misc.h ./tree234.h ./puttymem.h \
+		./puttyps.h ./network.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./winhelp.h charset/charset.h
+uxcfg.o: unix/uxcfg.c ./putty.h ./dialog.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+uxcons.o: unix/uxcons.c ./putty.h ./storage.h ./ssh.h ./puttyps.h \
+		./network.h ./misc.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./tree234.h ./winhelp.h \
+		charset/charset.h
+uxgen.o: unix/uxgen.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+uxmisc.o: unix/uxmisc.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+uxnet.o: unix/uxnet.c ./putty.h ./network.h ./tree234.h ./puttyps.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./winhelp.h charset/charset.h
+uxnoise.o: unix/uxnoise.c ./putty.h ./ssh.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./puttymem.h ./int64.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./tree234.h ./winhelp.h \
+		charset/charset.h
+uxplink.o: unix/uxplink.c ./putty.h ./storage.h ./tree234.h ./puttyps.h \
+		./network.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+uxprint.o: unix/uxprint.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+uxproxy.o: unix/uxproxy.c ./tree234.h ./putty.h ./network.h ./proxy.h \
+		./puttyps.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+uxputty.o: unix/uxputty.c ./putty.h ./storage.h ./puttyps.h ./network.h \
+		./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+uxsel.o: unix/uxsel.c ./putty.h ./tree234.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./winhelp.h charset/charset.h
+uxsftp.o: unix/uxsftp.c ./putty.h ./psftp.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+uxstore.o: unix/uxstore.c ./putty.h ./storage.h ./tree234.h ./puttyps.h \
+		./network.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./winhelp.h charset/charset.h
+uxucs.o: unix/uxucs.c ./putty.h charset/charset.h ./terminal.h ./misc.h \
+		./puttyps.h ./network.h ./tree234.h ./puttymem.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./winhelp.h
+version.o: ./version.c
+vsnprint.o: mac/vsnprint.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+wcwidth.o: ./wcwidth.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+wildcard.o: ./wildcard.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+win_res.res.o: ./win_res.rc ./win_res.h ./putty.ico ./puttycfg.ico
+wincfg.o: ./wincfg.c ./putty.h ./dialog.h ./storage.h ./puttyps.h \
+		./network.h ./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+winctrls.o: ./winctrls.c ./putty.h ./misc.h ./dialog.h ./puttyps.h \
+		./network.h ./puttymem.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
+windefs.o: ./windefs.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+windlg.o: ./windlg.c ./putty.h ./ssh.h ./win_res.h ./storage.h ./dialog.h \
+		./puttyps.h ./network.h ./misc.h ./puttymem.h ./int64.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./tree234.h \
+		./winhelp.h charset/charset.h
+window.o: ./window.c ./putty.h ./terminal.h ./storage.h ./win_res.h \
+		./puttyps.h ./network.h ./misc.h ./tree234.h ./winstuff.h \
+		mac/macstuff.h unix/unix.h ./puttymem.h ./winhelp.h \
+		charset/charset.h
+winmisc.o: ./winmisc.c ./putty.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+winnet.o: ./winnet.c ./putty.h ./network.h ./tree234.h ./puttyps.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./winhelp.h charset/charset.h
+winsftp.o: ./winsftp.c ./putty.h ./psftp.h ./puttyps.h ./network.h ./misc.h \
+		./winstuff.h mac/macstuff.h unix/unix.h ./puttymem.h \
+		./tree234.h ./winhelp.h charset/charset.h
+winstore.o: ./winstore.c ./putty.h ./storage.h ./puttyps.h ./network.h \
+		./misc.h ./winstuff.h mac/macstuff.h unix/unix.h \
+		./puttymem.h ./tree234.h ./winhelp.h charset/charset.h
+winutils.o: ./winutils.c ./misc.h ./puttymem.h
+x11fwd.o: ./x11fwd.c ./putty.h ./ssh.h ./puttyps.h ./network.h ./misc.h \
+		./puttymem.h ./int64.h ./winstuff.h mac/macstuff.h \
+		unix/unix.h ./tree234.h ./winhelp.h charset/charset.h
 xenc.o: charset/xenc.c charset/charset.h charset/internal.h
-xkeysym.o: unix/xkeysym.c misc.h puttymem.h
+xkeysym.o: unix/xkeysym.c ./misc.h ./puttymem.h
 
 version.o: FORCE;
-# Hack to force version.o to be rebuilt always
 FORCE:
 	$(CC) $(COMPAT) $(FWHACK) $(XFLAGS) $(CFLAGS) $(VER) -c version.c
+
 clean:
-	rm -f *.o *.exe *.res.o
+	rm -f *.o *.exe *.res.o *.map
 

+ 340 - 318
putty/MAKEFILE.LCC

@@ -1,4 +1,4 @@
-# Makefile for PuTTY under lcc.
+# Makefile for putty under lcc.
 #
 # This file was created by `mkfiles.pl' from the `Recipe' file.
 # DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.
@@ -81,7 +81,7 @@
 MAKEFILE = Makefile.lcc
 
 # C compilation flags
-CFLAGS = -D_WINDOWS
+CFLAGS = -D_WINDOWS -I./ -Icharset/ -Iunix/ -Imac/
 
 # Get include directory for resource compiler
 
@@ -161,28 +161,29 @@ psftp.exe: be_none.obj cmdline.obj console.obj int64.obj logging.obj \
 		imm32.lib
 
 putty.exe: be_all.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj noise.obj pageantc.obj \
-		portfwd.obj pproxy.obj printing.obj proxy.obj raw.obj \
-		rlogin.obj settings.obj sizetip.obj ssh.obj sshaes.obj \
-		sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj \
-		sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj sshrand.obj \
-		sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj telnet.obj \
-		terminal.obj tree234.obj unicode.obj version.obj wcwidth.obj \
-		wildcard.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj x11fwd.obj
+		ldiscucs.obj logging.obj minibidi.obj misc.obj noise.obj \
+		pageantc.obj portfwd.obj pproxy.obj printing.obj proxy.obj \
+		raw.obj rlogin.obj settings.obj sizetip.obj ssh.obj \
+		sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj \
+		sshdes.obj sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj \
+		sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj \
+		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
+		wcwidth.obj wildcard.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj x11fwd.obj
 	lcclnk -subsystem  windows -o putty.exe be_all.obj cmdline.obj config.obj \
-		dialog.obj ldisc.obj ldiscucs.obj logging.obj misc.obj \
-		noise.obj pageantc.obj portfwd.obj pproxy.obj printing.obj \
-		proxy.obj raw.obj rlogin.obj settings.obj sizetip.obj \
-		ssh.obj sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj \
-		sshcrcda.obj sshdes.obj sshdh.obj sshdss.obj sshmd5.obj \
-		sshpubk.obj sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj \
-		sshzlib.obj telnet.obj terminal.obj tree234.obj unicode.obj \
-		version.obj wcwidth.obj wildcard.obj win_res.res wincfg.obj \
-		winctrls.obj windefs.obj windlg.obj window.obj winmisc.obj \
-		winnet.obj winstore.obj winutils.obj x11fwd.obj shell32.lib \
-		wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib
+		dialog.obj ldisc.obj ldiscucs.obj logging.obj minibidi.obj \
+		misc.obj noise.obj pageantc.obj portfwd.obj pproxy.obj \
+		printing.obj proxy.obj raw.obj rlogin.obj settings.obj \
+		sizetip.obj ssh.obj sshaes.obj sshblowf.obj sshbn.obj \
+		sshcrc.obj sshcrcda.obj sshdes.obj sshdh.obj sshdss.obj \
+		sshmd5.obj sshpubk.obj sshrand.obj sshrsa.obj sshsh512.obj \
+		sshsha.obj sshzlib.obj telnet.obj terminal.obj tree234.obj \
+		unicode.obj version.obj wcwidth.obj wildcard.obj win_res.res \
+		wincfg.obj winctrls.obj windefs.obj windlg.obj window.obj \
+		winmisc.obj winnet.obj winstore.obj winutils.obj x11fwd.obj \
+		shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib \
+		imm32.lib
 
 puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
 		sshaes.obj sshbn.obj sshdes.obj sshdss.obj sshdssg.obj \
@@ -198,322 +199,343 @@ puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
 		winspool.lib winmm.lib imm32.lib
 
 puttytel.exe: be_nossh.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj pproxy.obj printing.obj \
-		proxy.obj raw.obj rlogin.obj settings.obj sizetip.obj \
-		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
-		wcwidth.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj
+		ldiscucs.obj logging.obj minibidi.obj misc.obj pproxy.obj \
+		printing.obj proxy.obj raw.obj rlogin.obj settings.obj \
+		sizetip.obj telnet.obj terminal.obj tree234.obj unicode.obj \
+		version.obj wcwidth.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj
 	lcclnk -subsystem  windows -o puttytel.exe be_nossh.obj cmdline.obj \
 		config.obj dialog.obj ldisc.obj ldiscucs.obj logging.obj \
-		misc.obj pproxy.obj printing.obj proxy.obj raw.obj \
-		rlogin.obj settings.obj sizetip.obj telnet.obj terminal.obj \
-		tree234.obj unicode.obj version.obj wcwidth.obj win_res.res \
-		wincfg.obj winctrls.obj windefs.obj windlg.obj window.obj \
-		winmisc.obj winnet.obj winstore.obj winutils.obj shell32.lib \
-		wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib
+		minibidi.obj misc.obj pproxy.obj printing.obj proxy.obj \
+		raw.obj rlogin.obj settings.obj sizetip.obj telnet.obj \
+		terminal.obj tree234.obj unicode.obj version.obj wcwidth.obj \
+		win_res.res wincfg.obj winctrls.obj windefs.obj windlg.obj \
+		window.obj winmisc.obj winnet.obj winstore.obj winutils.obj \
+		shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib \
+		imm32.lib
 
-be_all.obj: be_all.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_none.obj: be_none.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_nossh.obj: be_nossh.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-cmdgen.obj: cmdgen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-cmdline.obj: cmdline.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-config.obj: config.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-console.obj: console.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-dialog.obj: dialog.c putty.h dialog.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+be_all.obj: .\be_all.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_none.obj: .\be_none.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_nossh.obj: .\be_nossh.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+cmdgen.obj: .\cmdgen.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+cmdline.obj: .\cmdline.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+config.obj: .\config.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+console.obj: .\console.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+dialog.obj: .\dialog.c .\putty.h .\dialog.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 fromucs.obj: charset\fromucs.c charset\charset.h charset\internal.h
 gtkcols.obj: unix\gtkcols.c unix\gtkcols.h
-gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h putty.h storage.h \
-		dialog.h tree234.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
+gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h .\putty.h \
+		.\storage.h .\dialog.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
 gtkpanel.obj: unix\gtkpanel.c unix\gtkpanel.h
-import.obj: import.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-int64.obj: int64.c int64.h
-ldisc.obj: ldisc.c putty.h terminal.h ldisc.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ldiscucs.obj: ldiscucs.c putty.h terminal.h ldisc.h puttyps.h network.h \
-		misc.h tree234.h winstuff.h mac\macstuff.h unix\unix.h \
-		puttymem.h winhelp.h charset\charset.h
+import.obj: .\import.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+int64.obj: .\int64.c .\int64.h
+ldisc.obj: .\ldisc.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
+ldiscucs.obj: .\ldiscucs.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
 localenc.obj: charset\localenc.c charset\charset.h charset\internal.h
-logging.obj: logging.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mac.obj: mac\mac.c mac\macresid.h putty.h ssh.h terminal.h mac\mac.h \
-		puttyps.h network.h misc.h puttymem.h int64.h tree234.h \
-		charset\charset.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
+logging.obj: .\logging.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+mac.obj: mac\mac.c mac\macresid.h .\putty.h .\ssh.h .\terminal.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\tree234.h charset\charset.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 mac_res.res: mac\mac_res.r mac\macresid.h mac\version.r
-macabout.obj: mac\macabout.c putty.h mac\mac.h mac\macresid.h puttyps.h \
-		network.h misc.h charset\charset.h tree234.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macctrls.obj: mac\macctrls.c putty.h mac\mac.h mac\macresid.h dialog.h \
-		tree234.h puttyps.h network.h misc.h charset\charset.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macdlg.obj: mac\macdlg.c putty.h dialog.h mac\mac.h mac\macresid.h storage.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
+macabout.obj: mac\macabout.c .\putty.h mac\mac.h mac\macresid.h .\puttyps.h \
+		.\network.h .\misc.h charset\charset.h .\tree234.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\winhelp.h
+macctrls.obj: mac\macctrls.c .\putty.h mac\mac.h mac\macresid.h .\dialog.h \
+		.\tree234.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macdlg.obj: mac\macdlg.c .\putty.h .\dialog.h mac\mac.h mac\macresid.h \
+		.\storage.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
 macenc.obj: charset\macenc.c charset\charset.h charset\internal.h
-macevlog.obj: mac\macevlog.c putty.h mac\mac.h mac\macresid.h terminal.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macmisc.obj: mac\macmisc.c putty.h mac\mac.h puttyps.h network.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnet.obj: mac\macnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnoise.obj: mac\macnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-macpgen.obj: mac\macpgen.c mac\macpgrid.h putty.h ssh.h mac\mac.h puttyps.h \
-		network.h misc.h puttymem.h int64.h charset\charset.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h
+macevlog.obj: mac\macevlog.c .\putty.h mac\mac.h mac\macresid.h .\terminal.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macmisc.obj: mac\macmisc.c .\putty.h mac\mac.h .\puttyps.h .\network.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnet.obj: mac\macnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnoise.obj: mac\macnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+macpgen.obj: mac\macpgen.c mac\macpgrid.h .\putty.h .\ssh.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 macpgen.res: mac\macpgen.r mac\macpgrid.h mac\version.r
-macpgkey.obj: mac\macpgkey.c putty.h mac\mac.h mac\macpgrid.h ssh.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
-macstore.obj: mac\macstore.c putty.h storage.h mac\mac.h mac\macresid.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macterm.obj: mac\macterm.c mac\macresid.h putty.h charset\charset.h \
-		mac\mac.h terminal.h puttyps.h network.h misc.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macucs.obj: mac\macucs.c putty.h terminal.h misc.h mac\mac.h puttyps.h \
-		network.h tree234.h puttymem.h charset\charset.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
+macpgkey.obj: mac\macpgkey.c .\putty.h mac\mac.h mac\macpgrid.h .\ssh.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h
+macstore.obj: mac\macstore.c .\putty.h .\storage.h mac\mac.h mac\macresid.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macterm.obj: mac\macterm.c mac\macresid.h .\putty.h charset\charset.h \
+		mac\mac.h .\terminal.h .\puttyps.h .\network.h .\misc.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macucs.obj: mac\macucs.c .\putty.h .\terminal.h .\misc.h mac\mac.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\winhelp.h
 mimeenc.obj: charset\mimeenc.c charset\charset.h charset\internal.h
-misc.obj: misc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mtcpnet.obj: mac\mtcpnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-noise.obj: noise.c putty.h ssh.h storage.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-otnet.obj: mac\otnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-pageant.obj: pageant.c putty.h ssh.h misc.h tree234.h puttyps.h network.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
-pageant.res: pageant.rc pageant.ico pageants.ico
-pageantc.obj: pageantc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-plink.obj: plink.c putty.h storage.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-plink.res: plink.rc putty.ico
-portfwd.obj: portfwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-pproxy.obj: pproxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-printing.obj: printing.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-proxy.obj: proxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-psftp.obj: psftp.c putty.h psftp.h storage.h ssh.h sftp.h int64.h puttyps.h \
-		network.h misc.h puttymem.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-pterm.obj: unix\pterm.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ptermm.obj: unix\ptermm.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-pty.obj: unix\pty.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-puttygen.obj: puttygen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-puttygen.res: puttygen.rc puttygen.ico
-raw.obj: raw.c putty.h puttyps.h network.h misc.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h tree234.h winhelp.h charset\charset.h
-rlogin.obj: rlogin.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+minibidi.obj: .\minibidi.c .\minibidi.h
+misc.obj: .\misc.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+mtcpnet.obj: mac\mtcpnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+noise.obj: .\noise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+otnet.obj: mac\otnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
+pageant.obj: .\pageant.c .\putty.h .\ssh.h .\misc.h .\tree234.h .\puttyps.h \
+		.\network.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
+pageant.res: .\pageant.rc .\pageant.ico .\pageants.ico
+pageantc.obj: .\pageantc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+plink.obj: .\plink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+plink.res: .\plink.rc .\putty.ico
+portfwd.obj: .\portfwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+pproxy.obj: .\pproxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+printing.obj: .\printing.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+proxy.obj: .\proxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+psftp.obj: .\psftp.c .\putty.h .\psftp.h .\storage.h .\ssh.h .\sftp.h \
+		.\int64.h .\puttyps.h .\network.h .\misc.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+pterm.obj: unix\pterm.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+ptermm.obj: unix\ptermm.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+pty.obj: unix\pty.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+puttygen.obj: .\puttygen.c .\putty.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+puttygen.res: .\puttygen.rc .\puttygen.ico
+raw.obj: .\raw.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+rlogin.obj: .\rlogin.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 sbcs.obj: charset\sbcs.c charset\charset.h charset\internal.h
 sbcsdat.obj: charset\sbcsdat.c charset\charset.h charset\internal.h
-scp.obj: scp.c putty.h psftp.h ssh.h sftp.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-scp.res: scp.rc scp.ico
-settings.obj: settings.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-sftp.obj: sftp.c misc.h int64.h tree234.h sftp.h puttymem.h
+scp.obj: .\scp.c .\putty.h .\psftp.h .\ssh.h .\sftp.h .\storage.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+scp.res: .\scp.rc .\scp.ico
+settings.obj: .\settings.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+sftp.obj: .\sftp.c .\misc.h .\int64.h .\tree234.h .\sftp.h .\puttymem.h
 signal.obj: unix\signal.c
-sizetip.obj: sizetip.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+sizetip.obj: .\sizetip.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 slookup.obj: charset\slookup.c charset\charset.h charset\internal.h \
 		charset\enum.c charset\sbcsdat.c charset\utf8.c
-ssh.obj: ssh.c putty.h tree234.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h
-sshaes.obj: sshaes.c ssh.h puttymem.h network.h int64.h misc.h
-sshblowf.obj: sshblowf.c ssh.h puttymem.h network.h int64.h misc.h
-sshbn.obj: sshbn.c misc.h ssh.h puttymem.h network.h int64.h
-sshcrc.obj: sshcrc.c ssh.h puttymem.h network.h int64.h misc.h
-sshcrcda.obj: sshcrcda.c misc.h ssh.h puttymem.h network.h int64.h
-sshdes.obj: sshdes.c ssh.h puttymem.h network.h int64.h misc.h
-sshdh.obj: sshdh.c ssh.h puttymem.h network.h int64.h misc.h
-sshdss.obj: sshdss.c ssh.h misc.h puttymem.h network.h int64.h
-sshdssg.obj: sshdssg.c misc.h ssh.h puttymem.h network.h int64.h
-sshmd5.obj: sshmd5.c ssh.h puttymem.h network.h int64.h misc.h
-sshprime.obj: sshprime.c ssh.h puttymem.h network.h int64.h misc.h
-sshpubk.obj: sshpubk.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrand.obj: sshrand.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrsa.obj: sshrsa.c ssh.h misc.h puttymem.h network.h int64.h
-sshrsag.obj: sshrsag.c ssh.h puttymem.h network.h int64.h misc.h
-sshsh512.obj: sshsh512.c ssh.h puttymem.h network.h int64.h misc.h
-sshsha.obj: sshsha.c ssh.h puttymem.h network.h int64.h misc.h
-sshzlib.obj: sshzlib.c ssh.h puttymem.h network.h int64.h misc.h
-stricmp.obj: mac\stricmp.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-telnet.obj: telnet.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-terminal.obj: terminal.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-testback.obj: testback.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+ssh.obj: .\ssh.c .\putty.h .\tree234.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+sshaes.obj: .\sshaes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshblowf.obj: .\sshblowf.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshbn.obj: .\sshbn.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshcrc.obj: .\sshcrc.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshcrcda.obj: .\sshcrcda.c .\misc.h .\ssh.h .\puttymem.h .\network.h \
+		.\int64.h
+sshdes.obj: .\sshdes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdh.obj: .\sshdh.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdss.obj: .\sshdss.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshdssg.obj: .\sshdssg.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshmd5.obj: .\sshmd5.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshprime.obj: .\sshprime.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshpubk.obj: .\sshpubk.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrand.obj: .\sshrand.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrsa.obj: .\sshrsa.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshrsag.obj: .\sshrsag.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshsh512.obj: .\sshsh512.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshsha.obj: .\sshsha.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshzlib.obj: .\sshzlib.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+stricmp.obj: mac\stricmp.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+telnet.obj: .\telnet.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+terminal.obj: .\terminal.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+testback.obj: .\testback.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 toucs.obj: charset\toucs.c charset\charset.h charset\internal.h
-tree234.obj: tree234.c puttymem.h tree234.h
-unicode.obj: unicode.c putty.h terminal.h misc.h puttyps.h network.h \
-		tree234.h puttymem.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
+tree234.obj: .\tree234.c .\puttymem.h .\tree234.h
+unicode.obj: .\unicode.c .\putty.h .\terminal.h .\misc.h .\puttyps.h \
+		.\network.h .\tree234.h .\puttymem.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
 utf8.obj: charset\utf8.c charset\charset.h charset\internal.h
-ux_x11.obj: unix\ux_x11.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxagentc.obj: unix\uxagentc.c putty.h misc.h tree234.h puttymem.h puttyps.h \
-		network.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h
-uxcfg.obj: unix\uxcfg.c putty.h dialog.h storage.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		tree234.h winhelp.h charset\charset.h
-uxcons.obj: unix\uxcons.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-uxgen.obj: unix\uxgen.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxmisc.obj: unix\uxmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxnet.obj: unix\uxnet.c putty.h network.h tree234.h puttyps.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxnoise.obj: unix\uxnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-uxplink.obj: unix\uxplink.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxprint.obj: unix\uxprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxproxy.obj: unix\uxproxy.c tree234.h putty.h network.h proxy.h puttyps.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxputty.obj: unix\uxputty.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxsel.obj: unix\uxsel.c putty.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxsftp.obj: unix\uxsftp.c putty.h psftp.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxstore.obj: unix\uxstore.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxucs.obj: unix\uxucs.c putty.h charset\charset.h terminal.h misc.h \
-		puttyps.h network.h tree234.h puttymem.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
-version.obj: version.c
-vsnprint.obj: mac\vsnprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wcwidth.obj: wcwidth.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wildcard.obj: wildcard.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-win_res.res: win_res.rc win_res.h putty.ico puttycfg.ico
-wincfg.obj: wincfg.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winctrls.obj: winctrls.c putty.h misc.h dialog.h puttyps.h network.h \
-		puttymem.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-windefs.obj: windefs.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-windlg.obj: windlg.c putty.h ssh.h win_res.h storage.h dialog.h puttyps.h \
-		network.h misc.h puttymem.h int64.h winstuff.h \
-		mac\macstuff.h unix\unix.h tree234.h winhelp.h \
-		charset\charset.h
-window.obj: window.c putty.h terminal.h storage.h win_res.h puttyps.h \
-		network.h misc.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h charset\charset.h
-winmisc.obj: winmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winnet.obj: winnet.c putty.h network.h tree234.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-winsftp.obj: winsftp.c putty.h psftp.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winstore.obj: winstore.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winutils.obj: winutils.c misc.h puttymem.h
-x11fwd.obj: x11fwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
+ux_x11.obj: unix\ux_x11.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+uxagentc.obj: unix\uxagentc.c .\putty.h .\misc.h .\tree234.h .\puttymem.h \
+		.\puttyps.h .\network.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+uxcfg.obj: unix\uxcfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxcons.obj: unix\uxcons.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxgen.obj: unix\uxgen.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxmisc.obj: unix\uxmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxnet.obj: unix\uxnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxnoise.obj: unix\uxnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxplink.obj: unix\uxplink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxprint.obj: unix\uxprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxproxy.obj: unix\uxproxy.c .\tree234.h .\putty.h .\network.h .\proxy.h \
+		.\puttyps.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxputty.obj: unix\uxputty.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxsel.obj: unix\uxsel.c .\putty.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxsftp.obj: unix\uxsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxstore.obj: unix\uxstore.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxucs.obj: unix\uxucs.c .\putty.h charset\charset.h .\terminal.h .\misc.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\winhelp.h
+version.obj: .\version.c
+vsnprint.obj: mac\vsnprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wcwidth.obj: .\wcwidth.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wildcard.obj: .\wildcard.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+win_res.res: .\win_res.rc .\win_res.h .\putty.ico .\puttycfg.ico
+wincfg.obj: .\wincfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winctrls.obj: .\winctrls.c .\putty.h .\misc.h .\dialog.h .\puttyps.h \
+		.\network.h .\puttymem.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+windefs.obj: .\windefs.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+windlg.obj: .\windlg.c .\putty.h .\ssh.h .\win_res.h .\storage.h .\dialog.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+window.obj: .\window.c .\putty.h .\terminal.h .\storage.h .\win_res.h \
+		.\puttyps.h .\network.h .\misc.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h \
+		charset\charset.h
+winmisc.obj: .\winmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+winnet.obj: .\winnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+winsftp.obj: .\winsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winstore.obj: .\winstore.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winutils.obj: .\winutils.c .\misc.h .\puttymem.h
+x11fwd.obj: .\x11fwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
 xenc.obj: charset\xenc.c charset\charset.h charset\internal.h
-xkeysym.obj: unix\xkeysym.c misc.h puttymem.h
+xkeysym.obj: unix\xkeysym.c .\misc.h .\puttymem.h
 
 version.o: FORCE
-# Hack to force version.o to be rebuilt always
 FORCE:
 	lcc $(FWHACK) $(VER) $(CFLAGS) /c version.c
 

+ 354 - 347
putty/MAKEFILE.VC

@@ -1,4 +1,4 @@
-# Makefile for PuTTY under Visual C.
+# Makefile for putty under Visual C.
 #
 # This file was created by `mkfiles.pl' from the `Recipe' file.
 # DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.
@@ -75,26 +75,14 @@
 #      show up as GPFs at the point of failure rather than appearing
 #      later on as second-level damage.
 #
-#  - XFLAGS=/DGSSAPI
-#      Enable support for GSSAPI authentication in SSH 2
-#
 
 # If you rename this file to `Makefile', you should change this line,
 # so that the .rsp files still depend on the correct makefile.
 MAKEFILE = Makefile.vc
 
-# location of MIT's Kerberos for Windows SDK
-# (available here: http://web.mit.edu/kerberos/www/index.html)
-KRB5_DIR = "D:\Devel\Kerberos\kfw-2.6.1\kfw-2.6.1-sdk"
-
-XFLAGS = /I$(KRB5_DIR)\inc\krb5 /DGSSAPI
-#GSSAPILIBS = $(KRB5_DIR)\lib\i386\gssapi32.lib
-
-VER=/DRELEASE="0.54 - Kerberos 5 GSSAPI"
-
 # C compilation flags
 CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401
-LFLAGS = /incremental:no /fixed /opt:ref
+LFLAGS = /incremental:no /fixed
 
 .c.obj:
 	cl $(COMPAT) $(FWHACK) $(XFLAGS) $(CFLAGS) /c $*.c
@@ -110,7 +98,7 @@ pageant.exe: misc.obj pageant.obj pageant.res pageantc.obj sshaes.obj \
 		winmisc.obj winutils.obj pageant.rsp
 	link $(LFLAGS) -out:pageant.exe -map:pageant.map @pageant.rsp
 
-plink.exe: be_all.obj buffer.obj cmdline.obj console.obj ldisc.obj logging.obj misc.obj \
+plink.exe: be_all.obj cmdline.obj console.obj ldisc.obj logging.obj misc.obj \
 		noise.obj pageantc.obj plink.obj plink.res portfwd.obj \
 		pproxy.obj proxy.obj raw.obj rlogin.obj settings.obj ssh.obj \
 		sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj \
@@ -118,9 +106,9 @@ plink.exe: be_all.obj buffer.obj cmdline.obj console.obj ldisc.obj logging.obj m
 		sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj \
 		telnet.obj tree234.obj version.obj wildcard.obj windefs.obj \
 		winmisc.obj winnet.obj winstore.obj x11fwd.obj plink.rsp
-	link $(LFLAGS) -out:plink.exe -map:plink.map $(GSSAPILIBS) @plink.rsp
+	link $(LFLAGS) -out:plink.exe -map:plink.map @plink.rsp
 
-pscp.exe: be_none.obj buffer.obj cmdline.obj console.obj int64.obj logging.obj misc.obj \
+pscp.exe: be_none.obj cmdline.obj console.obj int64.obj logging.obj misc.obj \
 		noise.obj pageantc.obj portfwd.obj pproxy.obj proxy.obj \
 		scp.obj scp.res settings.obj sftp.obj ssh.obj sshaes.obj \
 		sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj \
@@ -128,9 +116,9 @@ pscp.exe: be_none.obj buffer.obj cmdline.obj console.obj int64.obj logging.obj m
 		sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj tree234.obj \
 		version.obj wildcard.obj windefs.obj winmisc.obj winnet.obj \
 		winsftp.obj winstore.obj x11fwd.obj pscp.rsp
-	link $(LFLAGS) -out:pscp.exe -map:pscp.map $(GSSAPILIBS) @pscp.rsp
+	link $(LFLAGS) -out:pscp.exe -map:pscp.map @pscp.rsp
 
-psftp.exe: be_none.obj buffer.obj cmdline.obj console.obj int64.obj logging.obj \
+psftp.exe: be_none.obj cmdline.obj console.obj int64.obj logging.obj \
 		misc.obj noise.obj pageantc.obj portfwd.obj pproxy.obj \
 		proxy.obj psftp.obj scp.res settings.obj sftp.obj ssh.obj \
 		sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj \
@@ -138,20 +126,20 @@ psftp.exe: be_none.obj buffer.obj cmdline.obj console.obj int64.obj logging.obj
 		sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj \
 		tree234.obj version.obj wildcard.obj windefs.obj winmisc.obj \
 		winnet.obj winsftp.obj winstore.obj x11fwd.obj psftp.rsp
-	link $(LFLAGS) -out:psftp.exe -map:psftp.map $(GSSAPILIBS) @psftp.rsp
+	link $(LFLAGS) -out:psftp.exe -map:psftp.map @psftp.rsp
 
-putty.exe: be_all.obj buffer.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj noise.obj pageantc.obj \
-		portfwd.obj pproxy.obj printing.obj proxy.obj raw.obj \
-		rlogin.obj settings.obj sizetip.obj ssh.obj sshaes.obj \
-		sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj \
-		sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj sshrand.obj \
-		sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj telnet.obj \
-		terminal.obj tree234.obj unicode.obj version.obj wcwidth.obj \
-		wildcard.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj x11fwd.obj putty.rsp
-	link $(LFLAGS) -out:putty.exe -map:putty.map $(GSSAPILIBS) @putty.rsp
+putty.exe: be_all.obj cmdline.obj config.obj dialog.obj ldisc.obj \
+		ldiscucs.obj logging.obj minibidi.obj misc.obj noise.obj \
+		pageantc.obj portfwd.obj pproxy.obj printing.obj proxy.obj \
+		raw.obj rlogin.obj settings.obj sizetip.obj ssh.obj \
+		sshaes.obj sshblowf.obj sshbn.obj sshcrc.obj sshcrcda.obj \
+		sshdes.obj sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj \
+		sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj \
+		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
+		wcwidth.obj wildcard.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj x11fwd.obj putty.rsp
+	link $(LFLAGS) -out:putty.exe -map:putty.map @putty.rsp
 
 puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
 		sshaes.obj sshbn.obj sshdes.obj sshdss.obj sshdssg.obj \
@@ -162,12 +150,12 @@ puttygen.exe: import.obj misc.obj noise.obj puttygen.obj puttygen.res \
 	link $(LFLAGS) -out:puttygen.exe -map:puttygen.map @puttygen.rsp
 
 puttytel.exe: be_nossh.obj cmdline.obj config.obj dialog.obj ldisc.obj \
-		ldiscucs.obj logging.obj misc.obj pproxy.obj printing.obj \
-		proxy.obj raw.obj rlogin.obj settings.obj sizetip.obj \
-		telnet.obj terminal.obj tree234.obj unicode.obj version.obj \
-		wcwidth.obj win_res.res wincfg.obj winctrls.obj windefs.obj \
-		windlg.obj window.obj winmisc.obj winnet.obj winstore.obj \
-		winutils.obj puttytel.rsp
+		ldiscucs.obj logging.obj minibidi.obj misc.obj pproxy.obj \
+		printing.obj proxy.obj raw.obj rlogin.obj settings.obj \
+		sizetip.obj telnet.obj terminal.obj tree234.obj unicode.obj \
+		version.obj wcwidth.obj win_res.res wincfg.obj winctrls.obj \
+		windefs.obj windlg.obj window.obj winmisc.obj winnet.obj \
+		winstore.obj winutils.obj puttytel.rsp
 	link $(LFLAGS) -out:puttytel.exe -map:puttytel.map @puttytel.rsp
 
 pageant.rsp: $(MAKEFILE)
@@ -182,7 +170,7 @@ pageant.rsp: $(MAKEFILE)
 
 plink.rsp: $(MAKEFILE)
 	echo /nologo /subsystem:console > plink.rsp
-	echo advapi32.lib be_all.obj buffer.obj cmdline.obj comctl32.lib >> plink.rsp
+	echo advapi32.lib be_all.obj cmdline.obj comctl32.lib >> plink.rsp
 	echo comdlg32.lib console.obj gdi32.lib imm32.lib >> plink.rsp
 	echo ldisc.obj logging.obj misc.obj noise.obj >> plink.rsp
 	echo pageantc.obj plink.obj plink.res portfwd.obj >> plink.rsp
@@ -198,7 +186,7 @@ plink.rsp: $(MAKEFILE)
 
 pscp.rsp: $(MAKEFILE)
 	echo /nologo /subsystem:console > pscp.rsp
-	echo advapi32.lib be_none.obj buffer.obj cmdline.obj comctl32.lib >> pscp.rsp
+	echo advapi32.lib be_none.obj cmdline.obj comctl32.lib >> pscp.rsp
 	echo comdlg32.lib console.obj gdi32.lib imm32.lib >> pscp.rsp
 	echo int64.obj logging.obj misc.obj noise.obj >> pscp.rsp
 	echo pageantc.obj portfwd.obj pproxy.obj proxy.obj >> pscp.rsp
@@ -213,7 +201,7 @@ pscp.rsp: $(MAKEFILE)
 
 psftp.rsp: $(MAKEFILE)
 	echo /nologo /subsystem:console > psftp.rsp
-	echo advapi32.lib be_none.obj buffer.obj cmdline.obj comctl32.lib >> psftp.rsp
+	echo advapi32.lib be_none.obj cmdline.obj comctl32.lib >> psftp.rsp
 	echo comdlg32.lib console.obj gdi32.lib imm32.lib >> psftp.rsp
 	echo int64.obj logging.obj misc.obj noise.obj >> psftp.rsp
 	echo pageantc.obj portfwd.obj pproxy.obj proxy.obj >> psftp.rsp
@@ -229,22 +217,22 @@ psftp.rsp: $(MAKEFILE)
 
 putty.rsp: $(MAKEFILE)
 	echo /nologo /subsystem:windows > putty.rsp
-	echo advapi32.lib be_all.obj buffer.obj cmdline.obj comctl32.lib >> putty.rsp
+	echo advapi32.lib be_all.obj cmdline.obj comctl32.lib >> putty.rsp
 	echo comdlg32.lib config.obj dialog.obj gdi32.lib >> putty.rsp
 	echo imm32.lib ldisc.obj ldiscucs.obj logging.obj >> putty.rsp
-	echo misc.obj noise.obj pageantc.obj portfwd.obj >> putty.rsp
-	echo pproxy.obj printing.obj proxy.obj raw.obj >> putty.rsp
-	echo rlogin.obj settings.obj shell32.lib sizetip.obj >> putty.rsp
-	echo ssh.obj sshaes.obj sshblowf.obj sshbn.obj >> putty.rsp
-	echo sshcrc.obj sshcrcda.obj sshdes.obj sshdh.obj >> putty.rsp
-	echo sshdss.obj sshmd5.obj sshpubk.obj sshrand.obj >> putty.rsp
-	echo sshrsa.obj sshsh512.obj sshsha.obj sshzlib.obj >> putty.rsp
-	echo telnet.obj terminal.obj tree234.obj unicode.obj >> putty.rsp
-	echo user32.lib version.obj wcwidth.obj wildcard.obj >> putty.rsp
-	echo win_res.res wincfg.obj winctrls.obj windefs.obj >> putty.rsp
-	echo windlg.obj window.obj winmisc.obj winmm.lib >> putty.rsp
-	echo winnet.obj winspool.lib winstore.obj winutils.obj >> putty.rsp
-	echo x11fwd.obj >> putty.rsp
+	echo minibidi.obj misc.obj noise.obj pageantc.obj >> putty.rsp
+	echo portfwd.obj pproxy.obj printing.obj proxy.obj >> putty.rsp
+	echo raw.obj rlogin.obj settings.obj shell32.lib >> putty.rsp
+	echo sizetip.obj ssh.obj sshaes.obj sshblowf.obj >> putty.rsp
+	echo sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj >> putty.rsp
+	echo sshdh.obj sshdss.obj sshmd5.obj sshpubk.obj >> putty.rsp
+	echo sshrand.obj sshrsa.obj sshsh512.obj sshsha.obj >> putty.rsp
+	echo sshzlib.obj telnet.obj terminal.obj tree234.obj >> putty.rsp
+	echo unicode.obj user32.lib version.obj wcwidth.obj >> putty.rsp
+	echo wildcard.obj win_res.res wincfg.obj winctrls.obj >> putty.rsp
+	echo windefs.obj windlg.obj window.obj winmisc.obj >> putty.rsp
+	echo winmm.lib winnet.obj winspool.lib winstore.obj >> putty.rsp
+	echo winutils.obj x11fwd.obj >> putty.rsp
 
 puttygen.rsp: $(MAKEFILE)
 	echo /nologo /subsystem:windows > puttygen.rsp
@@ -263,316 +251,335 @@ puttytel.rsp: $(MAKEFILE)
 	echo advapi32.lib be_nossh.obj cmdline.obj >> puttytel.rsp
 	echo comctl32.lib comdlg32.lib config.obj dialog.obj >> puttytel.rsp
 	echo gdi32.lib imm32.lib ldisc.obj ldiscucs.obj >> puttytel.rsp
-	echo logging.obj misc.obj pproxy.obj printing.obj >> puttytel.rsp
-	echo proxy.obj raw.obj rlogin.obj settings.obj >> puttytel.rsp
-	echo shell32.lib sizetip.obj telnet.obj terminal.obj >> puttytel.rsp
-	echo tree234.obj unicode.obj user32.lib version.obj >> puttytel.rsp
-	echo wcwidth.obj win_res.res wincfg.obj winctrls.obj >> puttytel.rsp
-	echo windefs.obj windlg.obj window.obj winmisc.obj >> puttytel.rsp
-	echo winmm.lib winnet.obj winspool.lib winstore.obj >> puttytel.rsp
-	echo winutils.obj >> puttytel.rsp
+	echo logging.obj minibidi.obj misc.obj pproxy.obj >> puttytel.rsp
+	echo printing.obj proxy.obj raw.obj rlogin.obj >> puttytel.rsp
+	echo settings.obj shell32.lib sizetip.obj telnet.obj >> puttytel.rsp
+	echo terminal.obj tree234.obj unicode.obj user32.lib >> puttytel.rsp
+	echo version.obj wcwidth.obj win_res.res wincfg.obj >> puttytel.rsp
+	echo winctrls.obj windefs.obj windlg.obj window.obj >> puttytel.rsp
+	echo winmisc.obj winmm.lib winnet.obj winspool.lib >> puttytel.rsp
+	echo winstore.obj winutils.obj >> puttytel.rsp
 
-be_all.obj: be_all.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_none.obj: be_none.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-be_nossh.obj: be_nossh.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-buffer.obj: buffer.c puttymem.h
-cmdgen.obj: cmdgen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-cmdline.obj: cmdline.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-config.obj: config.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-console.obj: console.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-dialog.obj: dialog.c putty.h dialog.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+be_all.obj: .\be_all.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_none.obj: .\be_none.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+be_nossh.obj: .\be_nossh.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+cmdgen.obj: .\cmdgen.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+cmdline.obj: .\cmdline.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+config.obj: .\config.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+console.obj: .\console.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+dialog.obj: .\dialog.c .\putty.h .\dialog.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 fromucs.obj: charset\fromucs.c charset\charset.h charset\internal.h
 gtkcols.obj: unix\gtkcols.c unix\gtkcols.h
-gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h putty.h storage.h \
-		dialog.h tree234.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
+gtkdlg.obj: unix\gtkdlg.c unix\gtkcols.h unix\gtkpanel.h .\putty.h \
+		.\storage.h .\dialog.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
 gtkpanel.obj: unix\gtkpanel.c unix\gtkpanel.h
-import.obj: import.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-int64.obj: int64.c int64.h
-ldisc.obj: ldisc.c putty.h terminal.h ldisc.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ldiscucs.obj: ldiscucs.c putty.h terminal.h ldisc.h puttyps.h network.h \
-		misc.h tree234.h winstuff.h mac\macstuff.h unix\unix.h \
-		puttymem.h winhelp.h charset\charset.h
+import.obj: .\import.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+int64.obj: .\int64.c .\int64.h
+ldisc.obj: .\ldisc.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
+ldiscucs.obj: .\ldiscucs.c .\putty.h .\terminal.h .\ldisc.h .\puttyps.h \
+		.\network.h .\misc.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h charset\charset.h
 localenc.obj: charset\localenc.c charset\charset.h charset\internal.h
-logging.obj: logging.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mac.obj: mac\mac.c mac\macresid.h putty.h ssh.h terminal.h mac\mac.h \
-		puttyps.h network.h misc.h puttymem.h int64.h tree234.h \
-		charset\charset.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
+logging.obj: .\logging.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+mac.obj: mac\mac.c mac\macresid.h .\putty.h .\ssh.h .\terminal.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\tree234.h charset\charset.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 mac_res.res: mac\mac_res.r mac\macresid.h mac\version.r
-macabout.obj: mac\macabout.c putty.h mac\mac.h mac\macresid.h puttyps.h \
-		network.h misc.h charset\charset.h tree234.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macctrls.obj: mac\macctrls.c putty.h mac\mac.h mac\macresid.h dialog.h \
-		tree234.h puttyps.h network.h misc.h charset\charset.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macdlg.obj: mac\macdlg.c putty.h dialog.h mac\mac.h mac\macresid.h storage.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
+macabout.obj: mac\macabout.c .\putty.h mac\mac.h mac\macresid.h .\puttyps.h \
+		.\network.h .\misc.h charset\charset.h .\tree234.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\winhelp.h
+macctrls.obj: mac\macctrls.c .\putty.h mac\mac.h mac\macresid.h .\dialog.h \
+		.\tree234.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macdlg.obj: mac\macdlg.c .\putty.h .\dialog.h mac\mac.h mac\macresid.h \
+		.\storage.h .\puttyps.h .\network.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
 macenc.obj: charset\macenc.c charset\charset.h charset\internal.h
-macevlog.obj: mac\macevlog.c putty.h mac\mac.h mac\macresid.h terminal.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macmisc.obj: mac\macmisc.c putty.h mac\mac.h puttyps.h network.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnet.obj: mac\macnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-macnoise.obj: mac\macnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-macpgen.obj: mac\macpgen.c mac\macpgrid.h putty.h ssh.h mac\mac.h puttyps.h \
-		network.h misc.h puttymem.h int64.h charset\charset.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h
+macevlog.obj: mac\macevlog.c .\putty.h mac\mac.h mac\macresid.h .\terminal.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macmisc.obj: mac\macmisc.c .\putty.h mac\mac.h .\puttyps.h .\network.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnet.obj: mac\macnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+macnoise.obj: mac\macnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+macpgen.obj: mac\macpgen.c mac\macpgrid.h .\putty.h .\ssh.h mac\mac.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h
 macpgen.res: mac\macpgen.r mac\macpgrid.h mac\version.r
-macpgkey.obj: mac\macpgkey.c putty.h mac\mac.h mac\macpgrid.h ssh.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h
-macstore.obj: mac\macstore.c putty.h storage.h mac\mac.h mac\macresid.h \
-		puttyps.h network.h misc.h charset\charset.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macterm.obj: mac\macterm.c mac\macresid.h putty.h charset\charset.h \
-		mac\mac.h terminal.h puttyps.h network.h misc.h tree234.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h
-macucs.obj: mac\macucs.c putty.h terminal.h misc.h mac\mac.h puttyps.h \
-		network.h tree234.h puttymem.h charset\charset.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
+macpgkey.obj: mac\macpgkey.c .\putty.h mac\mac.h mac\macpgrid.h .\ssh.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h
+macstore.obj: mac\macstore.c .\putty.h .\storage.h mac\mac.h mac\macresid.h \
+		.\puttyps.h .\network.h .\misc.h charset\charset.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macterm.obj: mac\macterm.c mac\macresid.h .\putty.h charset\charset.h \
+		mac\mac.h .\terminal.h .\puttyps.h .\network.h .\misc.h \
+		.\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h
+macucs.obj: mac\macucs.c .\putty.h .\terminal.h .\misc.h mac\mac.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		charset\charset.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\winhelp.h
 mimeenc.obj: charset\mimeenc.c charset\charset.h charset\internal.h
-misc.obj: misc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-mtcpnet.obj: mac\mtcpnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-noise.obj: noise.c putty.h ssh.h storage.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-otnet.obj: mac\otnet.c putty.h network.h mac\mac.h puttyps.h misc.h \
-		charset\charset.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h
-pageant.obj: pageant.c putty.h ssh.h misc.h tree234.h puttyps.h network.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
-pageant.res: pageant.rc pageant.ico pageants.ico
-pageantc.obj: pageantc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-plink.obj: plink.c putty.h storage.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-plink.res: plink.rc putty.ico
-portfwd.obj: portfwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-pproxy.obj: pproxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-printing.obj: printing.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-proxy.obj: proxy.c putty.h network.h proxy.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-psftp.obj: psftp.c putty.h psftp.h storage.h ssh.h sftp.h int64.h puttyps.h \
-		network.h misc.h puttymem.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-pterm.obj: unix\pterm.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-ptermm.obj: unix\ptermm.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-pty.obj: unix\pty.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-puttygen.obj: puttygen.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-puttygen.res: puttygen.rc puttygen.ico
-raw.obj: raw.c putty.h puttyps.h network.h misc.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h tree234.h winhelp.h charset\charset.h
-rlogin.obj: rlogin.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+minibidi.obj: .\minibidi.c .\minibidi.h
+misc.obj: .\misc.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+mtcpnet.obj: mac\mtcpnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h \
+		.\misc.h charset\charset.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h
+noise.obj: .\noise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+otnet.obj: mac\otnet.c .\putty.h .\network.h mac\mac.h .\puttyps.h .\misc.h \
+		charset\charset.h .\tree234.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\puttymem.h .\winhelp.h
+pageant.obj: .\pageant.c .\putty.h .\ssh.h .\misc.h .\tree234.h .\puttyps.h \
+		.\network.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
+pageant.res: .\pageant.rc .\pageant.ico .\pageants.ico
+pageantc.obj: .\pageantc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+plink.obj: .\plink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+plink.res: .\plink.rc .\putty.ico
+portfwd.obj: .\portfwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+pproxy.obj: .\pproxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+printing.obj: .\printing.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+proxy.obj: .\proxy.c .\putty.h .\network.h .\proxy.h .\puttyps.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+psftp.obj: .\psftp.c .\putty.h .\psftp.h .\storage.h .\ssh.h .\sftp.h \
+		.\int64.h .\puttyps.h .\network.h .\misc.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+pterm.obj: unix\pterm.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+ptermm.obj: unix\ptermm.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+pty.obj: unix\pty.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+puttygen.obj: .\puttygen.c .\putty.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+puttygen.res: .\puttygen.rc .\puttygen.ico
+raw.obj: .\raw.c .\putty.h .\puttyps.h .\network.h .\misc.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+rlogin.obj: .\rlogin.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 sbcs.obj: charset\sbcs.c charset\charset.h charset\internal.h
 sbcsdat.obj: charset\sbcsdat.c charset\charset.h charset\internal.h
-scp.obj: scp.c putty.h psftp.h ssh.h sftp.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-scp.res: scp.rc scp.ico
-settings.obj: settings.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-sftp.obj: sftp.c misc.h int64.h tree234.h sftp.h puttymem.h
+scp.obj: .\scp.c .\putty.h .\psftp.h .\ssh.h .\sftp.h .\storage.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+scp.res: .\scp.rc .\scp.ico
+settings.obj: .\settings.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+sftp.obj: .\sftp.c .\misc.h .\int64.h .\tree234.h .\sftp.h .\puttymem.h
 signal.obj: unix\signal.c
-sizetip.obj: sizetip.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+sizetip.obj: .\sizetip.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 slookup.obj: charset\slookup.c charset\charset.h charset\internal.h \
 		charset\enum.c charset\sbcsdat.c charset\utf8.c
-ssh.obj: ssh.c putty.h tree234.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h buffer.h buffer.c
-sshaes.obj: sshaes.c ssh.h puttymem.h network.h int64.h misc.h
-sshblowf.obj: sshblowf.c ssh.h puttymem.h network.h int64.h misc.h
-sshbn.obj: sshbn.c misc.h ssh.h puttymem.h network.h int64.h
-sshcrc.obj: sshcrc.c ssh.h puttymem.h network.h int64.h misc.h
-sshcrcda.obj: sshcrcda.c misc.h ssh.h puttymem.h network.h int64.h
-sshdes.obj: sshdes.c ssh.h puttymem.h network.h int64.h misc.h
-sshdh.obj: sshdh.c ssh.h puttymem.h network.h int64.h misc.h
-sshdss.obj: sshdss.c ssh.h misc.h puttymem.h network.h int64.h
-sshdssg.obj: sshdssg.c misc.h ssh.h puttymem.h network.h int64.h
-sshmd5.obj: sshmd5.c ssh.h puttymem.h network.h int64.h misc.h
-sshprime.obj: sshprime.c ssh.h puttymem.h network.h int64.h misc.h
-sshpubk.obj: sshpubk.c putty.h ssh.h misc.h puttyps.h network.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrand.obj: sshrand.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-sshrsa.obj: sshrsa.c ssh.h misc.h puttymem.h network.h int64.h
-sshrsag.obj: sshrsag.c ssh.h puttymem.h network.h int64.h misc.h
-sshsh512.obj: sshsh512.c ssh.h puttymem.h network.h int64.h misc.h
-sshsha.obj: sshsha.c ssh.h puttymem.h network.h int64.h misc.h
-sshzlib.obj: sshzlib.c ssh.h puttymem.h network.h int64.h misc.h
-stricmp.obj: mac\stricmp.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-telnet.obj: telnet.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-terminal.obj: terminal.c putty.h terminal.h puttyps.h network.h misc.h \
-		tree234.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-testback.obj: testback.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
+ssh.obj: .\ssh.c .\putty.h .\tree234.h .\ssh.h .\puttyps.h .\network.h \
+		.\misc.h .\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+sshaes.obj: .\sshaes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshblowf.obj: .\sshblowf.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshbn.obj: .\sshbn.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshcrc.obj: .\sshcrc.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshcrcda.obj: .\sshcrcda.c .\misc.h .\ssh.h .\puttymem.h .\network.h \
+		.\int64.h
+sshdes.obj: .\sshdes.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdh.obj: .\sshdh.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshdss.obj: .\sshdss.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshdssg.obj: .\sshdssg.c .\misc.h .\ssh.h .\puttymem.h .\network.h .\int64.h
+sshmd5.obj: .\sshmd5.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshprime.obj: .\sshprime.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshpubk.obj: .\sshpubk.c .\putty.h .\ssh.h .\misc.h .\puttyps.h .\network.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrand.obj: .\sshrand.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+sshrsa.obj: .\sshrsa.c .\ssh.h .\misc.h .\puttymem.h .\network.h .\int64.h
+sshrsag.obj: .\sshrsag.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshsh512.obj: .\sshsh512.c .\ssh.h .\puttymem.h .\network.h .\int64.h \
+		.\misc.h
+sshsha.obj: .\sshsha.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+sshzlib.obj: .\sshzlib.c .\ssh.h .\puttymem.h .\network.h .\int64.h .\misc.h
+stricmp.obj: mac\stricmp.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+telnet.obj: .\telnet.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+terminal.obj: .\terminal.c .\putty.h .\terminal.h .\puttyps.h .\network.h \
+		.\misc.h .\tree234.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+testback.obj: .\testback.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
 toucs.obj: charset\toucs.c charset\charset.h charset\internal.h
-tree234.obj: tree234.c puttymem.h tree234.h
-unicode.obj: unicode.c putty.h terminal.h misc.h puttyps.h network.h \
-		tree234.h puttymem.h winstuff.h mac\macstuff.h unix\unix.h \
-		winhelp.h charset\charset.h
+tree234.obj: .\tree234.c .\puttymem.h .\tree234.h
+unicode.obj: .\unicode.c .\putty.h .\terminal.h .\misc.h .\puttyps.h \
+		.\network.h .\tree234.h .\puttymem.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\winhelp.h charset\charset.h
 utf8.obj: charset\utf8.c charset\charset.h charset\internal.h
-ux_x11.obj: unix\ux_x11.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxagentc.obj: unix\uxagentc.c putty.h misc.h tree234.h puttymem.h puttyps.h \
-		network.h winstuff.h mac\macstuff.h unix\unix.h winhelp.h \
-		charset\charset.h
-uxcfg.obj: unix\uxcfg.c putty.h dialog.h storage.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		tree234.h winhelp.h charset\charset.h
-uxcons.obj: unix\uxcons.c putty.h storage.h ssh.h puttyps.h network.h misc.h \
-		puttymem.h int64.h winstuff.h mac\macstuff.h unix\unix.h \
-		tree234.h winhelp.h charset\charset.h
-uxgen.obj: unix\uxgen.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxmisc.obj: unix\uxmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxnet.obj: unix\uxnet.c putty.h network.h tree234.h puttyps.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxnoise.obj: unix\uxnoise.c putty.h ssh.h storage.h puttyps.h network.h \
-		misc.h puttymem.h int64.h winstuff.h mac\macstuff.h \
-		unix\unix.h tree234.h winhelp.h charset\charset.h
-uxplink.obj: unix\uxplink.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxprint.obj: unix\uxprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-uxproxy.obj: unix\uxproxy.c tree234.h putty.h network.h proxy.h puttyps.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxputty.obj: unix\uxputty.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxsel.obj: unix\uxsel.c putty.h tree234.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-uxsftp.obj: unix\uxsftp.c putty.h psftp.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-uxstore.obj: unix\uxstore.c putty.h storage.h tree234.h puttyps.h network.h \
-		misc.h winstuff.h mac\macstuff.h unix\unix.h puttymem.h \
-		winhelp.h charset\charset.h
-uxucs.obj: unix\uxucs.c putty.h charset\charset.h terminal.h misc.h \
-		puttyps.h network.h tree234.h puttymem.h winstuff.h \
-		mac\macstuff.h unix\unix.h winhelp.h
-version.obj: version.c
-vsnprint.obj: mac\vsnprint.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wcwidth.obj: wcwidth.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-wildcard.obj: wildcard.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-win_res.res: win_res.rc win_res.h putty.ico puttycfg.ico
-wincfg.obj: wincfg.c putty.h dialog.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winctrls.obj: winctrls.c putty.h misc.h dialog.h puttyps.h network.h \
-		puttymem.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
-windefs.obj: windefs.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-windlg.obj: windlg.c putty.h ssh.h win_res.h storage.h dialog.h puttyps.h \
-		network.h misc.h puttymem.h int64.h winstuff.h \
-		mac\macstuff.h unix\unix.h tree234.h winhelp.h \
-		charset\charset.h
-window.obj: window.c putty.h terminal.h storage.h win_res.h puttyps.h \
-		network.h misc.h tree234.h winstuff.h mac\macstuff.h \
-		unix\unix.h puttymem.h winhelp.h charset\charset.h
-winmisc.obj: winmisc.c putty.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winnet.obj: winnet.c putty.h network.h tree234.h puttyps.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h winhelp.h \
-		charset\charset.h
-winsftp.obj: winsftp.c putty.h psftp.h puttyps.h network.h misc.h winstuff.h \
-		mac\macstuff.h unix\unix.h puttymem.h tree234.h winhelp.h \
-		charset\charset.h
-winstore.obj: winstore.c putty.h storage.h puttyps.h network.h misc.h \
-		winstuff.h mac\macstuff.h unix\unix.h puttymem.h tree234.h \
-		winhelp.h charset\charset.h
-winutils.obj: winutils.c misc.h puttymem.h
-x11fwd.obj: x11fwd.c putty.h ssh.h puttyps.h network.h misc.h puttymem.h \
-		int64.h winstuff.h mac\macstuff.h unix\unix.h tree234.h \
-		winhelp.h charset\charset.h
+ux_x11.obj: unix\ux_x11.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+uxagentc.obj: unix\uxagentc.c .\putty.h .\misc.h .\tree234.h .\puttymem.h \
+		.\puttyps.h .\network.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\winhelp.h charset\charset.h
+uxcfg.obj: unix\uxcfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxcons.obj: unix\uxcons.c .\putty.h .\storage.h .\ssh.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxgen.obj: unix\uxgen.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxmisc.obj: unix\uxmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxnet.obj: unix\uxnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxnoise.obj: unix\uxnoise.c .\putty.h .\ssh.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\puttymem.h .\int64.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\tree234.h .\winhelp.h \
+		charset\charset.h
+uxplink.obj: unix\uxplink.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxprint.obj: unix\uxprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+uxproxy.obj: unix\uxproxy.c .\tree234.h .\putty.h .\network.h .\proxy.h \
+		.\puttyps.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxputty.obj: unix\uxputty.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxsel.obj: unix\uxsel.c .\putty.h .\tree234.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxsftp.obj: unix\uxsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+uxstore.obj: unix\uxstore.c .\putty.h .\storage.h .\tree234.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+uxucs.obj: unix\uxucs.c .\putty.h charset\charset.h .\terminal.h .\misc.h \
+		.\puttyps.h .\network.h .\tree234.h .\puttymem.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\winhelp.h
+version.obj: .\version.c
+vsnprint.obj: mac\vsnprint.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wcwidth.obj: .\wcwidth.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+wildcard.obj: .\wildcard.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+win_res.res: .\win_res.rc .\win_res.h .\putty.ico .\puttycfg.ico
+wincfg.obj: .\wincfg.c .\putty.h .\dialog.h .\storage.h .\puttyps.h \
+		.\network.h .\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winctrls.obj: .\winctrls.c .\putty.h .\misc.h .\dialog.h .\puttyps.h \
+		.\network.h .\puttymem.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
+windefs.obj: .\windefs.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+windlg.obj: .\windlg.c .\putty.h .\ssh.h .\win_res.h .\storage.h .\dialog.h \
+		.\puttyps.h .\network.h .\misc.h .\puttymem.h .\int64.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\tree234.h \
+		.\winhelp.h charset\charset.h
+window.obj: .\window.c .\putty.h .\terminal.h .\storage.h .\win_res.h \
+		.\puttyps.h .\network.h .\misc.h .\tree234.h .\winstuff.h \
+		mac\macstuff.h unix\unix.h .\puttymem.h .\winhelp.h \
+		charset\charset.h
+winmisc.obj: .\winmisc.c .\putty.h .\puttyps.h .\network.h .\misc.h \
+		.\winstuff.h mac\macstuff.h unix\unix.h .\puttymem.h \
+		.\tree234.h .\winhelp.h charset\charset.h
+winnet.obj: .\winnet.c .\putty.h .\network.h .\tree234.h .\puttyps.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\winhelp.h charset\charset.h
+winsftp.obj: .\winsftp.c .\putty.h .\psftp.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winstore.obj: .\winstore.c .\putty.h .\storage.h .\puttyps.h .\network.h \
+		.\misc.h .\winstuff.h mac\macstuff.h unix\unix.h \
+		.\puttymem.h .\tree234.h .\winhelp.h charset\charset.h
+winutils.obj: .\winutils.c .\misc.h .\puttymem.h
+x11fwd.obj: .\x11fwd.c .\putty.h .\ssh.h .\puttyps.h .\network.h .\misc.h \
+		.\puttymem.h .\int64.h .\winstuff.h mac\macstuff.h \
+		unix\unix.h .\tree234.h .\winhelp.h charset\charset.h
 xenc.obj: charset\xenc.c charset\charset.h charset\internal.h
-xkeysym.obj: unix\xkeysym.c misc.h puttymem.h
+xkeysym.obj: unix\xkeysym.c .\misc.h .\puttymem.h
 
-# Hack to force version.o to be rebuilt always
 version.obj: *.c *.h *.rc
 	cl $(FWHACK) $(VER) $(CFLAGS) /c version.c
 

+ 1788 - 0
putty/MINIBIDI.C

@@ -0,0 +1,1788 @@
+/************************************************************************
+ * $Id: minibidi.c,v 1.1 2004/05/22 10:36:50 simon Exp $
+ *
+ * ------------
+ * Description:
+ * ------------
+ * This is an implemention of Unicode's Bidirectional Algorithm
+ * (known as UAX #9).
+ *
+ *   http://www.unicode.org/reports/tr9/
+ * 
+ * Author: Ahmad Khalifa
+ *
+ * -----------------
+ * Revision Details:    (Updated by Revision Control System)
+ * -----------------
+ *  $Date: 2004/05/22 10:36:50 $
+ *  $Author: simon $
+ *  $Revision: 1.1 $
+ *  $Source: /home/cvs/putty/minibidi.c,v $
+ *
+ * (www.arabeyes.org - under MIT license)
+ *
+ ************************************************************************/
+
+/*
+ * TODO:
+ * =====
+ * - Explicit marks need to be handled (they are not 100% now)
+ * - Ligatures
+ */
+
+#include "minibidi.h"
+
+/*
+ * Flips the text buffer, according to max level, and
+ * all higher levels
+ * 
+ * Input:
+ * from: text buffer, on which to apply flipping
+ * level: resolved levels buffer
+ * max: the maximum level found in this line (should be unsigned char)
+ * count: line size in bidi_char
+ */
+void flipThisRun(bidi_char *from, unsigned char *level, int max, int count)
+{
+    int i, j, rcount, tlevel;
+    bidi_char temp;
+
+    j = i = 0;
+    while(i<count && j<count)
+    {
+
+	/* find the start of the run of level=max */
+	tlevel = max;
+	i = j = findIndexOfRun(level, i, count, max);
+	/* find the end of the run */
+	while(tlevel <= level[i] && i<count)
+	{
+	    i++;
+	}
+	rcount = i-j;
+	for(; rcount>((i-j)/2); rcount--)
+	{
+	    temp = from[j+rcount-1];
+	    from[j+rcount-1] = from[i-rcount];
+	    from[i-rcount] = temp;
+	}
+    }
+}
+
+/*
+ * Finds the index of a run with level equals tlevel
+ */
+int findIndexOfRun(unsigned char* level , int start, int count, int tlevel)
+{
+    int i;
+    for(i=start; i<count; i++)
+    {
+	if(tlevel == level[i])
+	{
+	    return i;
+	}
+    }
+    return count;
+}
+
+/*
+ * Returns character type of ch, by calling RLE table lookup
+ * function
+ */
+unsigned char getType(wchar_t ch)
+{
+    return getRLE(ch);
+}
+
+/*
+ * The most significant 2 bits of each level are used to store
+ * Override status of each character
+ * This function sets the override bits of level according
+ * to the value in override, and reurns the new byte.
+ */
+unsigned char setOverrideBits(unsigned char level, unsigned char override)
+{
+    if(override == ON)
+	return level;
+    else if(override == R)
+	return level | OISR;
+    else if(override == L)
+	return level | OISL;
+    return level;
+}
+
+/* Dont remember what this was used for :-) */
+unsigned char getPreviousLevel(unsigned char* level, int from)
+{
+    unsigned char current;
+    from--;
+    current = level[from];
+    while(from>0 && level[from] == current)
+    {
+	from--;
+    }
+    return level[++from];
+}
+
+/*
+ * Returns the first odd value greater than x
+ */
+unsigned char leastGreaterOdd(unsigned char x)
+{
+    if((x % 2) == 0)
+	return x+1;
+    else
+	return x+2;
+}
+
+/*
+ * Returns the first even value greater than x
+ */
+unsigned char leastGreaterEven(unsigned char x)
+{
+    if((x % 2) == 0)
+	return x+2;
+    else
+	return x+1;
+}
+
+/*
+ * Loops over the RLE_table array looking for the
+ * type of ch
+ */
+unsigned char getRLE(wchar_t ch)
+{
+    int offset, i, freq;
+
+    freq = offset = 0;
+    for(i=0; i<0xFFFF; i++)
+    {
+	freq = ((RLENode*)RLE_table)[i].f;
+	offset += freq;
+	if(offset == ch)
+	    return ((RLENode*)RLE_table)[i].d;
+	else if(offset > ch)
+	    return ((RLENode*)RLE_table)[i-1].d;
+    }
+    /* this is here to stop compiler nagging */
+    return ON;
+}
+
+/* The Main shaping function, and the only one to be used
+ * by the outside world.
+ *
+ * line: buffer to apply shaping to. this must be passed by doBidi() first
+ * to: output buffer for the shaped data
+ * count: number of characters in line
+ */
+int do_shape(bidi_char *line, bidi_char *to, int count)
+{
+    int i, tempShape, ligFlag;
+
+    for(ligFlag=i=0; i<count; i++)
+    {
+	to[i] = line[i];
+	tempShape = STYPE(line[i].wc);
+	switch(tempShape )
+	{
+	  case SC:
+	    break;
+
+	  case SU:
+	    break;
+
+	  case SR:
+	    tempShape = STYPE(line[i+1].wc);
+	    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+		to[i].wc = SFINAL((SISOLATED(line[i].wc)));
+	    else
+		to[i].wc = SISOLATED(line[i].wc);
+	    break;
+
+
+	  case SD:
+	    /* Make Ligatures */
+	    tempShape = STYPE(line[i+1].wc);
+	    if(line[i].wc == 0x644)
+	    {
+		switch(line[i-1].wc)
+		{
+		  case 0x622:
+		    ligFlag = 1;
+		    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+			to[i].wc = 0xFEF6;
+		    else
+			to[i].wc = 0xFEF5;
+		    break;
+		  case 0x623:
+		    ligFlag = 1;
+		    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+			to[i].wc = 0xFEF8;
+		    else
+			to[i].wc = 0xFEF7;
+		    break;
+		  case 0x625:
+		    ligFlag = 1;
+		    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+			to[i].wc = 0xFEFA;
+		    else
+			to[i].wc = 0xFEF9;
+		    break;
+		  case 0x627:
+		    ligFlag = 1;
+		    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+			to[i].wc = 0xFEFC;
+		    else
+			to[i].wc = 0xFEFB;
+		    break;
+		}
+		if(ligFlag)
+		{
+		    to[i-1].wc = 0x20;
+		    ligFlag = 0;
+		    break;
+		}
+	    }
+
+	    if((tempShape == SL) || (tempShape == SD) || (tempShape == SC))
+	    {
+		tempShape = STYPE(line[i-1].wc);
+		if((tempShape == SR) || (tempShape == SD) || (tempShape == SC))
+		    to[i].wc = SMEDIAL( (SISOLATED(line[i].wc)) );
+		else
+		    to[i].wc = SFINAL((SISOLATED(line[i].wc)));
+		break;
+	    }
+
+	    tempShape = STYPE(line[i-1].wc);
+	    if((tempShape == SR) || (tempShape == SD) || (tempShape == SC))
+		to[i].wc = SINITIAL((SISOLATED(line[i].wc)));
+	    else
+		to[i].wc = SISOLATED(line[i].wc);
+	    break;
+
+
+	}
+    }
+    return 1;
+}
+
+/*
+ * The Main Bidi Function, and the only function that should
+ * be used by the outside world.
+ *
+ * line: a buffer of size count containing text to apply
+ * the Bidirectional algorithm to.
+ */
+
+int do_bidi(bidi_char *line, int count)
+{
+    unsigned char* types;
+    unsigned char* levels;
+    unsigned char paragraphLevel;
+    unsigned char currentEmbedding;
+    unsigned char currentOverride;
+    unsigned char tempType;
+    int i, j, imax, yes, bover;
+
+    /* Check the presence of R or AL types as optimization */
+    yes = 0;
+    for(i=0; i<count; i++)
+    {
+	if(getType(line[i].wc) == R || getType(line[i].wc) == AL)
+	{
+	    yes = 1;
+	    break;
+	}
+    }
+    if(yes == 0)
+	return L;
+
+    /* Initialize types, levels */
+    types = malloc(sizeof(unsigned char) * count);
+    levels = malloc(sizeof(unsigned char) * count);
+
+    /* Rule (P1)  NOT IMPLEMENTED
+     * P1. Split the text into separate paragraphs. A paragraph separator is
+     * kept with the previous paragraph. Within each paragraph, apply all the
+     * other rules of this algorithm.
+     */
+
+    /* Rule (P2), (P3)
+     * P2. In each paragraph, find the first character of type L, AL, or R.
+     * P3. If a character is found in P2 and it is of type AL or R, then set
+     * the paragraph embedding level to one; otherwise, set it to zero.
+     */
+    paragraphLevel = 0;
+    for( i=0; i<count ; i++)
+    {
+	if(getType(line[i].wc) == R || getType(line[i].wc) == AL)
+	{
+	    paragraphLevel = 1;
+	    break;
+	}
+	else if(getType(line[i].wc) == L)
+	    break;
+    }
+
+    /* Rule (X1)
+     * X1. Begin by setting the current embedding level to the paragraph
+     * embedding level. Set the directional override status to neutral.
+     */
+    currentEmbedding = paragraphLevel;
+    currentOverride = ON;
+
+    /* Rule (X2), (X3), (X4), (X5), (X6), (X7), (X8)
+     * X2. With each RLE, compute the least greater odd embedding level.
+     * X3. With each LRE, compute the least greater even embedding level.
+     * X4. With each RLO, compute the least greater odd embedding level.
+     * X5. With each LRO, compute the least greater even embedding level.
+     * X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
+     *		a. Set the level of the current character to the current
+     *		    embedding level.
+     *		b.  Whenever the directional override status is not neutral,
+     *               reset the current character type to the directional
+     *               override status.
+     * X7. With each PDF, determine the matching embedding or override code.
+     * If there was a valid matching code, restore (pop) the last
+     * remembered (pushed) embedding level and directional override.
+     * X8. All explicit directional embeddings and overrides are completely
+     * terminated at the end of each paragraph. Paragraph separators are not
+     * included in the embedding. (Useless here) NOT IMPLEMENTED
+     */
+    bover = 0;
+    for( i=0; i<count; i++)
+    {
+	tempType = getType(line[i].wc);
+	switch(tempType)
+	{
+	  case RLE:
+	    currentEmbedding = levels[i] = leastGreaterOdd(currentEmbedding);
+	    levels[i] = setOverrideBits(levels[i], currentOverride);
+	    currentOverride = ON;
+	    break;
+
+	  case LRE:
+	    currentEmbedding = levels[i] = leastGreaterEven(currentEmbedding);
+	    levels[i] = setOverrideBits(levels[i], currentOverride);
+	    currentOverride = ON;
+	    break;
+
+	  case RLO:
+	    currentEmbedding = levels[i] = leastGreaterOdd(currentEmbedding);
+	    tempType = currentOverride = R;
+	    bover = 1;
+	    break;
+
+	  case LRO:
+	    currentEmbedding = levels[i] = leastGreaterEven(currentEmbedding);
+	    tempType = currentOverride = L;
+	    bover = 1;
+	    break;
+
+	  case PDF:
+	    currentEmbedding = getPreviousLevel(levels, i);
+	    currentOverride = currentEmbedding & OMASK;
+	    currentEmbedding = currentEmbedding & ~OMASK;
+	    levels[i] = currentEmbedding;
+	    break;
+
+	    /* Whitespace is treated as neutral for now */
+	  case WS:
+	  case S:
+	    levels[i] = currentEmbedding;
+	    tempType = ON;
+	    if(currentOverride != ON)
+		tempType = currentOverride;
+	    break;
+
+	  default:
+	    levels[i] = currentEmbedding;
+	    if(currentOverride != ON)
+		tempType = currentOverride;
+	    break;
+
+	}
+	types[i] = tempType;
+    }
+    /* this clears out all overrides, so we can use levels safely... */
+    /* checks bover first */
+    if(bover)
+	for( i=0; i<count; i++)
+	    levels[i] = levels[i] & LMASK;
+
+    /* Rule (X9)
+     * X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes.
+     * Here, they're converted to BN.
+     */
+    for(i=0; i<count; i++)
+    {
+	switch(types[i])
+	{
+	  case RLE:
+	  case LRE:
+	  case RLO:
+	  case LRO:
+	  case PDF:
+	    types[i] = BN;
+	    break;
+	}
+    }
+
+    /* Rule (W1)
+     * W1. Examine each non-spacing mark (NSM) in the level run, and change
+     * the type of the NSM to the type of the previous character. If the NSM
+     * is at the start of the level run, it will get the type of sor.
+     */
+    if(types[0] == NSM)
+	types[0] = paragraphLevel;
+
+    for(i=1; i<count; i++)
+    {
+	if(types[i] == NSM)
+	    types[i] = types[i-1];
+	/* Is this a safe assumption?
+	 * I assumed the previous, IS a character.
+	 */
+    }
+
+    /* Rule (W2)
+     * W2. Search backwards from each instance of a European number until the
+     * first strong type (R, L, AL, or sor) is found.  If an AL is found,
+     * change the type of the European number to Arabic number.
+     */
+    for(i=0; i<count; i++)
+    {
+	if(types[i] == EN)
+	{
+	    j=i;
+	    while(j >= 0)
+	    {
+		if(types[j] == AL)
+		{
+		    types[i] = AN;
+		    break;
+		}else if(types[j] == R || types[j] == L)
+		    {
+			break;
+		    }
+		j--;
+	    }
+	}
+    }
+
+    /* Rule (W3)
+     * W3. Change all ALs to R.
+     *
+     * Optimization: on Rule Xn, we might set a flag on AL type
+     * to prevent this loop in L R lines only...
+     */
+    for(i=0; i<count; i++)
+    {
+	if(types[i] == AL)
+	    types[i] = R;
+    }
+
+    /* Rule (W4)
+     * W4. A single European separator between two European numbers changes
+     * to a European number. A single common separator between two numbers
+     * of the same type changes to that type.
+     */
+    for( i=0; i<(count-1); i++)
+    {
+	if(types[i] == ES)
+	{
+	    if(types[i-1] == EN && types[i+1] == EN)
+		types[i] = EN;
+	}else if(types[i] == CS)
+	    {
+		if(types[i-1] == EN && types[i+1] == EN)
+		    types[i] = EN;
+		else if(types[i-1] == AN && types[i+1] == AN)
+		    types[i] = AN;
+	    }
+    }
+
+    /* Rule (W5)
+     * W5. A sequence of European terminators adjacent to European numbers
+     * changes to all European numbers.
+     *
+     * Optimization: lots here... else ifs need rearrangement
+     */
+    for(i=0; i<count; i++)
+    {
+	if(types[i] == ET)
+	{
+	    if(types[i-1] == EN)
+	    {
+		types[i] = EN;
+		continue;
+	    }else if(types[i+1] == EN)
+		{
+		    types[i] = EN;
+		    continue;
+		}else if(types[i+1] == ET)
+		    {
+			j=i;
+			while(j <count && types[j] == ET)
+			{
+			    j++;
+			}
+			if(types[j] == EN)
+			    types[i] = EN;
+		    }
+	}
+    }
+
+    /* Rule (W6)
+     * W6. Otherwise, separators and terminators change to Other Neutral:
+     */
+    for(i=0; i<count; i++)
+    {
+	switch(types[i])
+	{
+	  case ES:
+	  case ET:
+	  case CS:
+	    types[i] = ON;
+	    break;
+	}
+    }
+
+    /* Rule (W7)
+     * W7. Search backwards from each instance of a European number until
+     * the first strong type (R, L, or sor) is found. If an L is found,
+     * then change the type of the European number to L.
+     */
+    for(i=0; i<count; i++)
+    {
+	if(types[i] == EN)
+	{
+	    j=i;
+	    while(j >= 0)
+	    {
+		if(types[j] == L)
+		{
+		    types[i] = L;
+		    break;
+		}
+		else if(types[j] == R || types[j] == AL)
+		{
+		    break;
+		}
+		j--;
+	    }
+	}
+    }
+
+    /* Rule (N1)
+     * N1. A sequence of neutrals takes the direction of the surrounding
+     * strong text if the text on both sides has the same direction. European
+     * and Arabic numbers are treated as though they were R.
+     */
+    if(types[0] == ON)
+    {
+	if((types[1] == R) || (types[1] == EN) || (types[1] == AN))
+	    types[0] = R;
+	else if(types[1] == L)
+	    types[0] = L;
+    }
+    for(i=1; i<(count-1); i++)
+    {
+	if(types[i] == ON)
+	{
+	    if(types[i-1] == L)
+	    {
+		j=i;
+		while(j<(count-1) && types[j] == ON)
+		{
+		    j++;
+		}
+		if(types[j] == L)
+		{
+		    while(i<j)
+		    {
+			types[i] = L;
+			i++;
+		    }
+		}
+
+	    }else if((types[i-1] == R)  ||
+		     (types[i-1] == EN) ||
+		     (types[i-1] == AN))
+		{
+		    j=i;
+		    while(j<(count-1) && types[j] == ON)
+		    {
+			j++;
+		    }
+		    if((types[j] == R)  ||
+		       (types[j] == EN) ||
+		       (types[j] == AN))
+		    {
+			while(i<j)
+			{
+			    types[i] = R;
+			    i++;
+			}
+		    }
+		}
+	}
+    }
+    if(types[count-1] == ON)
+    {
+	if(types[count-2] == R || types[count-2] == EN || types[count-2] == AN)
+	    types[count-1] = R;
+	else if(types[count-2] == L)
+	    types[count-1] = L;
+    }
+
+    /* Rule (N2)
+     * N2. Any remaining neutrals take the embedding direction.
+     */
+    for(i=0; i<count; i++)
+    {
+	if(types[i] == ON)
+	{
+	    if((levels[i] % 2) == 0)
+		types[i] = L;
+	    else
+		types[i] = R;
+	}
+    }
+
+    /* Rule (I1)
+     * I1. For all characters with an even (left-to-right) embedding
+     * direction, those of type R go up one level and those of type AN or
+     * EN go up two levels.
+     */
+    for(i=0; i<count; i++)
+    {
+	if((levels[i] % 2) == 0)
+	{
+	    if(types[i] == R)
+		levels[i] += 1;
+	    else if(types[i] == AN || types[i] == EN)
+		levels[i] += 2;
+	}
+    }
+
+    /* Rule (I2)
+     * I2. For all characters with an odd (right-to-left) embedding direction,
+     * those of type L, EN or AN go up one level.
+     */
+    for(i=0; i<count; i++)
+    {
+	if((levels[i] % 2) == 1)
+	{
+	    if(types[i] == L || types[i] == EN || types[i] == AN)
+		levels[i] += 1;
+	}
+    }
+
+    /* Rule (L1)
+     * L1. On each line, reset the embedding level of the following characters
+     * to the paragraph embedding level:
+     *		(1)segment separators, (2)paragraph separators,
+     *           (3)any sequence of whitespace characters preceding
+     *           a segment separator or paragraph separator,
+     *           (4)and any sequence of white space characters
+     *           at the end of the line.
+     * The types of characters used here are the original types, not those
+     * modified by the previous phase.
+     */
+    j=count-1;
+    while(j>0 && (getType(line[j].wc) == WS))
+    {
+	j--;
+    }
+    if(j < (count-1))
+    {
+	for(j++; j<count; j++)
+	    levels[j] = paragraphLevel;
+    }
+    for(i=0; i<count; i++)
+    {
+	tempType = getType(line[i].wc);
+	if(tempType == WS)
+	{
+	    j=i;
+	    while(j<count && (getType(line[j].wc) == WS))
+	    {
+		j++;
+	    }
+	    if(getType(line[j].wc) == B || getType(line[j].wc) == S)
+	    {
+		for(j--; j>=i ; j--)
+		{
+		    levels[j] = paragraphLevel;
+		}
+	    }
+	}else if(tempType == B || tempType == S)
+		levels[i] = paragraphLevel;
+    }
+
+    /* Rule (L4) NOT IMPLEMENTED
+     * L4. A character that possesses the mirrored property as specified by
+     * Section 4.7, Mirrored, must be depicted by a mirrored glyph if the
+     * resolved directionality of that character is R.
+     */
+    /* Note: this is implemented before L2 for efficiency */
+    for(i=0; i<count; i++)
+	if((levels[i] % 2) == 1)
+	    doMirror(&line[i].wc);
+
+    /* Rule (L2)
+     * L2. From the highest level found in the text to the lowest odd level on
+     * each line, including intermediate levels not actually present in the
+     * text, reverse any contiguous sequence of characters that are at that
+     * level or higher
+     */
+    /* we flip the character string and leave the level array */
+    imax = 0;
+    i=0;
+    tempType = levels[0];
+    while(i < count)
+    {
+	if(levels[i] > tempType)
+	{
+	    tempType = levels[i];
+	    imax=i;
+	}
+	i++;
+    }
+    /* maximum level in tempType, its index in imax. */
+    while(tempType > 0)		/* loop from highest level to the least odd, */
+    {				/* which i assume is 1 */
+	flipThisRun(line, levels, tempType, count);
+	tempType--;
+    }
+
+    /* Rule (L3) NOT IMPLEMENTED
+     * L3. Combining marks applied to a right-to-left base character will at
+     * this point precede their base character. If the rendering engine
+     * expects them to follow the base characters in the final display
+     * process, then the ordering of the marks and the base character must
+     * be reversed.
+     */
+    free(types);
+    free(levels);
+    return R;
+}
+
+
+/*
+ * Bad, Horrible funtion
+ * takes a pointer to a character that is checked for
+ * having a mirror glyph.
+ */
+void doMirror(wchar_t* ch)
+{
+    if((*ch & 0xFF00) == 0)
+    {
+	switch(*ch)
+	{
+	  case 0x0028:
+	    *ch = 0x0029;
+	    break;
+	  case 0x0029:
+	    *ch = 0x0028;
+	    break;
+	  case 0x003C:
+	    *ch = 0x003E;
+	    break;
+	  case 0x003E:
+	    *ch = 0x003C;
+	    break;
+	  case 0x005B:
+	    *ch = 0x005D;
+	    break;
+	  case 0x005D:
+	    *ch = 0x005B;
+	    break;
+	  case 0x007B:
+	    *ch = 0x007D;
+	    break;
+	  case 0x007D:
+	    *ch = 0x007B;
+	    break;
+	  case 0x00AB:
+	    *ch = 0x00BB;
+	    break;
+	  case 0x00BB:
+	    *ch = 0x00AB;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0x2000)
+    {
+	switch(*ch)
+	{
+	  case 0x2039:
+	    *ch = 0x203A;
+	    break;
+	  case 0x203A:
+	    *ch = 0x2039;
+	    break;
+	  case 0x2045:
+	    *ch = 0x2046;
+	    break;
+	  case 0x2046:
+	    *ch = 0x2045;
+	    break;
+	  case 0x207D:
+	    *ch = 0x207E;
+	    break;
+	  case 0x207E:
+	    *ch = 0x207D;
+	    break;
+	  case 0x208D:
+	    *ch = 0x208E;
+	    break;
+	  case 0x208E:
+	    *ch = 0x208D;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0x2200)
+    {
+	switch(*ch)
+	{
+	  case 0x2208:
+	    *ch = 0x220B;
+	    break;
+	  case 0x2209:
+	    *ch = 0x220C;
+	    break;
+	  case 0x220A:
+	    *ch = 0x220D;
+	    break;
+	  case 0x220B:
+	    *ch = 0x2208;
+	    break;
+	  case 0x220C:
+	    *ch = 0x2209;
+	    break;
+	  case 0x220D:
+	    *ch = 0x220A;
+	    break;
+	  case 0x2215:
+	    *ch = 0x29F5;
+	    break;
+	  case 0x223C:
+	    *ch = 0x223D;
+	    break;
+	  case 0x223D:
+	    *ch = 0x223C;
+	    break;
+	  case 0x2243:
+	    *ch = 0x22CD;
+	    break;
+	  case 0x2252:
+	    *ch = 0x2253;
+	    break;
+	  case 0x2253:
+	    *ch = 0x2252;
+	    break;
+	  case 0x2254:
+	    *ch = 0x2255;
+	    break;
+	  case 0x2255:
+	    *ch = 0x2254;
+	    break;
+	  case 0x2264:
+	    *ch = 0x2265;
+	    break;
+	  case 0x2265:
+	    *ch = 0x2264;
+	    break;
+	  case 0x2266:
+	    *ch = 0x2267;
+	    break;
+	  case 0x2267:
+	    *ch = 0x2266;
+	    break;
+	  case 0x2268:
+	    *ch = 0x2269;
+	    break;
+	  case 0x2269:
+	    *ch = 0x2268;
+	    break;
+	  case 0x226A:
+	    *ch = 0x226B;
+	    break;
+	  case 0x226B:
+	    *ch = 0x226A;
+	    break;
+	  case 0x226E:
+	    *ch = 0x226F;
+	    break;
+	  case 0x226F:
+	    *ch = 0x226E;
+	    break;
+	  case 0x2270:
+	    *ch = 0x2271;
+	    break;
+	  case 0x2271:
+	    *ch = 0x2270;
+	    break;
+	  case 0x2272:
+	    *ch = 0x2273;
+	    break;
+	  case 0x2273:
+	    *ch = 0x2272;
+	    break;
+	  case 0x2274:
+	    *ch = 0x2275;
+	    break;
+	  case 0x2275:
+	    *ch = 0x2274;
+	    break;
+	  case 0x2276:
+	    *ch = 0x2277;
+	    break;
+	  case 0x2277:
+	    *ch = 0x2276;
+	    break;
+	  case 0x2278:
+	    *ch = 0x2279;
+	    break;
+	  case 0x2279:
+	    *ch = 0x2278;
+	    break;
+	  case 0x227A:
+	    *ch = 0x227B;
+	    break;
+	  case 0x227B:
+	    *ch = 0x227A;
+	    break;
+	  case 0x227C:
+	    *ch = 0x227D;
+	    break;
+	  case 0x227D:
+	    *ch = 0x227C;
+	    break;
+	  case 0x227E:
+	    *ch = 0x227F;
+	    break;
+	  case 0x227F:
+	    *ch = 0x227E;
+	    break;
+	  case 0x2280:
+	    *ch = 0x2281;
+	    break;
+	  case 0x2281:
+	    *ch = 0x2280;
+	    break;
+	  case 0x2282:
+	    *ch = 0x2283;
+	    break;
+	  case 0x2283:
+	    *ch = 0x2282;
+	    break;
+	  case 0x2284:
+	    *ch = 0x2285;
+	    break;
+	  case 0x2285:
+	    *ch = 0x2284;
+	    break;
+	  case 0x2286:
+	    *ch = 0x2287;
+	    break;
+	  case 0x2287:
+	    *ch = 0x2286;
+	    break;
+	  case 0x2288:
+	    *ch = 0x2289;
+	    break;
+	  case 0x2289:
+	    *ch = 0x2288;
+	    break;
+	  case 0x228A:
+	    *ch = 0x228B;
+	    break;
+	  case 0x228B:
+	    *ch = 0x228A;
+	    break;
+	  case 0x228F:
+	    *ch = 0x2290;
+	    break;
+	  case 0x2290:
+	    *ch = 0x228F;
+	    break;
+	  case 0x2291:
+	    *ch = 0x2292;
+	    break;
+	  case 0x2292:
+	    *ch = 0x2291;
+	    break;
+	  case 0x2298:
+	    *ch = 0x29B8;
+	    break;
+	  case 0x22A2:
+	    *ch = 0x22A3;
+	    break;
+	  case 0x22A3:
+	    *ch = 0x22A2;
+	    break;
+	  case 0x22A6:
+	    *ch = 0x2ADE;
+	    break;
+	  case 0x22A8:
+	    *ch = 0x2AE4;
+	    break;
+	  case 0x22A9:
+	    *ch = 0x2AE3;
+	    break;
+	  case 0x22AB:
+	    *ch = 0x2AE5;
+	    break;
+	  case 0x22B0:
+	    *ch = 0x22B1;
+	    break;
+	  case 0x22B1:
+	    *ch = 0x22B0;
+	    break;
+	  case 0x22B2:
+	    *ch = 0x22B3;
+	    break;
+	  case 0x22B3:
+	    *ch = 0x22B2;
+	    break;
+	  case 0x22B4:
+	    *ch = 0x22B5;
+	    break;
+	  case 0x22B5:
+	    *ch = 0x22B4;
+	    break;
+	  case 0x22B6:
+	    *ch = 0x22B7;
+	    break;
+	  case 0x22B7:
+	    *ch = 0x22B6;
+	    break;
+	  case 0x22C9:
+	    *ch = 0x22CA;
+	    break;
+	  case 0x22CA:
+	    *ch = 0x22C9;
+	    break;
+	  case 0x22CB:
+	    *ch = 0x22CC;
+	    break;
+	  case 0x22CC:
+	    *ch = 0x22CB;
+	    break;
+	  case 0x22CD:
+	    *ch = 0x2243;
+	    break;
+	  case 0x22D0:
+	    *ch = 0x22D1;
+	    break;
+	  case 0x22D1:
+	    *ch = 0x22D0;
+	    break;
+	  case 0x22D6:
+	    *ch = 0x22D7;
+	    break;
+	  case 0x22D7:
+	    *ch = 0x22D6;
+	    break;
+	  case 0x22D8:
+	    *ch = 0x22D9;
+	    break;
+	  case 0x22D9:
+	    *ch = 0x22D8;
+	    break;
+	  case 0x22DA:
+	    *ch = 0x22DB;
+	    break;
+	  case 0x22DB:
+	    *ch = 0x22DA;
+	    break;
+	  case 0x22DC:
+	    *ch = 0x22DD;
+	    break;
+	  case 0x22DD:
+	    *ch = 0x22DC;
+	    break;
+	  case 0x22DE:
+	    *ch = 0x22DF;
+	    break;
+	  case 0x22DF:
+	    *ch = 0x22DE;
+	    break;
+	  case 0x22E0:
+	    *ch = 0x22E1;
+	    break;
+	  case 0x22E1:
+	    *ch = 0x22E0;
+	    break;
+	  case 0x22E2:
+	    *ch = 0x22E3;
+	    break;
+	  case 0x22E3:
+	    *ch = 0x22E2;
+	    break;
+	  case 0x22E4:
+	    *ch = 0x22E5;
+	    break;
+	  case 0x22E5:
+	    *ch = 0x22E4;
+	    break;
+	  case 0x22E6:
+	    *ch = 0x22E7;
+	    break;
+	  case 0x22E7:
+	    *ch = 0x22E6;
+	    break;
+	  case 0x22E8:
+	    *ch = 0x22E9;
+	    break;
+	  case 0x22E9:
+	    *ch = 0x22E8;
+	    break;
+	  case 0x22EA:
+	    *ch = 0x22EB;
+	    break;
+	  case 0x22EB:
+	    *ch = 0x22EA;
+	    break;
+	  case 0x22EC:
+	    *ch = 0x22ED;
+	    break;
+	  case 0x22ED:
+	    *ch = 0x22EC;
+	    break;
+	  case 0x22F0:
+	    *ch = 0x22F1;
+	    break;
+	  case 0x22F1:
+	    *ch = 0x22F0;
+	    break;
+	  case 0x22F2:
+	    *ch = 0x22FA;
+	    break;
+	  case 0x22F3:
+	    *ch = 0x22FB;
+	    break;
+	  case 0x22F4:
+	    *ch = 0x22FC;
+	    break;
+	  case 0x22F6:
+	    *ch = 0x22FD;
+	    break;
+	  case 0x22F7:
+	    *ch = 0x22FE;
+	    break;
+	  case 0x22FA:
+	    *ch = 0x22F2;
+	    break;
+	  case 0x22FB:
+	    *ch = 0x22F3;
+	    break;
+	  case 0x22FC:
+	    *ch = 0x22F4;
+	    break;
+	  case 0x22FD:
+	    *ch = 0x22F6;
+	    break;
+	  case 0x22FE:
+	    *ch = 0x22F7;
+	    break;
+	}
+    }else if((*ch & 0xFF00) == 0x2300)
+	{
+	    switch(*ch)
+	    {
+	      case 0x2308:
+		*ch = 0x2309;
+		break;
+	      case 0x2309:
+		*ch = 0x2308;
+		break;
+	      case 0x230A:
+		*ch = 0x230B;
+		break;
+	      case 0x230B:
+		*ch = 0x230A;
+		break;
+	      case 0x2329:
+		*ch = 0x232A;
+		break;
+	      case 0x232A:
+		*ch = 0x2329;
+		break;
+	    }
+	}
+    else if((*ch & 0xFF00) == 0x2700)
+    {
+	switch(*ch)
+	{
+	  case 0x2768:
+	    *ch = 0x2769;
+	    break;
+	  case 0x2769:
+	    *ch = 0x2768;
+	    break;
+	  case 0x276A:
+	    *ch = 0x276B;
+	    break;
+	  case 0x276B:
+	    *ch = 0x276A;
+	    break;
+	  case 0x276C:
+	    *ch = 0x276D;
+	    break;
+	  case 0x276D:
+	    *ch = 0x276C;
+	    break;
+	  case 0x276E:
+	    *ch = 0x276F;
+	    break;
+	  case 0x276F:
+	    *ch = 0x276E;
+	    break;
+	  case 0x2770:
+	    *ch = 0x2771;
+	    break;
+	  case 0x2771:
+	    *ch = 0x2770;
+	    break;
+	  case 0x2772:
+	    *ch = 0x2773;
+	    break;
+	  case 0x2773:
+	    *ch = 0x2772;
+	    break;
+	  case 0x2774:
+	    *ch = 0x2775;
+	    break;
+	  case 0x2775:
+	    *ch = 0x2774;
+	    break;
+	  case 0x27D5:
+	    *ch = 0x27D6;
+	    break;
+	  case 0x27D6:
+	    *ch = 0x27D5;
+	    break;
+	  case 0x27DD:
+	    *ch = 0x27DE;
+	    break;
+	  case 0x27DE:
+	    *ch = 0x27DD;
+	    break;
+	  case 0x27E2:
+	    *ch = 0x27E3;
+	    break;
+	  case 0x27E3:
+	    *ch = 0x27E2;
+	    break;
+	  case 0x27E4:
+	    *ch = 0x27E5;
+	    break;
+	  case 0x27E5:
+	    *ch = 0x27E4;
+	    break;
+	  case 0x27E6:
+	    *ch = 0x27E7;
+	    break;
+	  case 0x27E7:
+	    *ch = 0x27E6;
+	    break;
+	  case 0x27E8:
+	    *ch = 0x27E9;
+	    break;
+	  case 0x27E9:
+	    *ch = 0x27E8;
+	    break;
+	  case 0x27EA:
+	    *ch = 0x27EB;
+	    break;
+	  case 0x27EB:
+	    *ch = 0x27EA;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0x2900)
+    {
+	switch(*ch)
+	{
+	  case 0x2983:
+	    *ch = 0x2984;
+	    break;
+	  case 0x2984:
+	    *ch = 0x2983;
+	    break;
+	  case 0x2985:
+	    *ch = 0x2986;
+	    break;
+	  case 0x2986:
+	    *ch = 0x2985;
+	    break;
+	  case 0x2987:
+	    *ch = 0x2988;
+	    break;
+	  case 0x2988:
+	    *ch = 0x2987;
+	    break;
+	  case 0x2989:
+	    *ch = 0x298A;
+	    break;
+	  case 0x298A:
+	    *ch = 0x2989;
+	    break;
+	  case 0x298B:
+	    *ch = 0x298C;
+	    break;
+	  case 0x298C:
+	    *ch = 0x298B;
+	    break;
+	  case 0x298D:
+	    *ch = 0x2990;
+	    break;
+	  case 0x298E:
+	    *ch = 0x298F;
+	    break;
+	  case 0x298F:
+	    *ch = 0x298E;
+	    break;
+	  case 0x2990:
+	    *ch = 0x298D;
+	    break;
+	  case 0x2991:
+	    *ch = 0x2992;
+	    break;
+	  case 0x2992:
+	    *ch = 0x2991;
+	    break;
+	  case 0x2993:
+	    *ch = 0x2994;
+	    break;
+	  case 0x2994:
+	    *ch = 0x2993;
+	    break;
+	  case 0x2995:
+	    *ch = 0x2996;
+	    break;
+	  case 0x2996:
+	    *ch = 0x2995;
+	    break;
+	  case 0x2997:
+	    *ch = 0x2998;
+	    break;
+	  case 0x2998:
+	    *ch = 0x2997;
+	    break;
+	  case 0x29B8:
+	    *ch = 0x2298;
+	    break;
+	  case 0x29C0:
+	    *ch = 0x29C1;
+	    break;
+	  case 0x29C1:
+	    *ch = 0x29C0;
+	    break;
+	  case 0x29C4:
+	    *ch = 0x29C5;
+	    break;
+	  case 0x29C5:
+	    *ch = 0x29C4;
+	    break;
+	  case 0x29CF:
+	    *ch = 0x29D0;
+	    break;
+	  case 0x29D0:
+	    *ch = 0x29CF;
+	    break;
+	  case 0x29D1:
+	    *ch = 0x29D2;
+	    break;
+	  case 0x29D2:
+	    *ch = 0x29D1;
+	    break;
+	  case 0x29D4:
+	    *ch = 0x29D5;
+	    break;
+	  case 0x29D5:
+	    *ch = 0x29D4;
+	    break;
+	  case 0x29D8:
+	    *ch = 0x29D9;
+	    break;
+	  case 0x29D9:
+	    *ch = 0x29D8;
+	    break;
+	  case 0x29DA:
+	    *ch = 0x29DB;
+	    break;
+	  case 0x29DB:
+	    *ch = 0x29DA;
+	    break;
+	  case 0x29F5:
+	    *ch = 0x2215;
+	    break;
+	  case 0x29F8:
+	    *ch = 0x29F9;
+	    break;
+	  case 0x29F9:
+	    *ch = 0x29F8;
+	    break;
+	  case 0x29FC:
+	    *ch = 0x29FD;
+	    break;
+	  case 0x29FD:
+	    *ch = 0x29FC;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0x2A00)
+    {
+	switch(*ch)
+	{
+	  case 0x2A2B:
+	    *ch = 0x2A2C;
+	    break;
+	  case 0x2A2C:
+	    *ch = 0x2A2B;
+	    break;
+	  case 0x2A2D:
+	    *ch = 0x2A2C;
+	    break;
+	  case 0x2A2E:
+	    *ch = 0x2A2D;
+	    break;
+	  case 0x2A34:
+	    *ch = 0x2A35;
+	    break;
+	  case 0x2A35:
+	    *ch = 0x2A34;
+	    break;
+	  case 0x2A3C:
+	    *ch = 0x2A3D;
+	    break;
+	  case 0x2A3D:
+	    *ch = 0x2A3C;
+	    break;
+	  case 0x2A64:
+	    *ch = 0x2A65;
+	    break;
+	  case 0x2A65:
+	    *ch = 0x2A64;
+	    break;
+	  case 0x2A79:
+	    *ch = 0x2A7A;
+	    break;
+	  case 0x2A7A:
+	    *ch = 0x2A79;
+	    break;
+	  case 0x2A7D:
+	    *ch = 0x2A7E;
+	    break;
+	  case 0x2A7E:
+	    *ch = 0x2A7D;
+	    break;
+	  case 0x2A7F:
+	    *ch = 0x2A80;
+	    break;
+	  case 0x2A80:
+	    *ch = 0x2A7F;
+	    break;
+	  case 0x2A81:
+	    *ch = 0x2A82;
+	    break;
+	  case 0x2A82:
+	    *ch = 0x2A81;
+	    break;
+	  case 0x2A83:
+	    *ch = 0x2A84;
+	    break;
+	  case 0x2A84:
+	    *ch = 0x2A83;
+	    break;
+	  case 0x2A8B:
+	    *ch = 0x2A8C;
+	    break;
+	  case 0x2A8C:
+	    *ch = 0x2A8B;
+	    break;
+	  case 0x2A91:
+	    *ch = 0x2A92;
+	    break;
+	  case 0x2A92:
+	    *ch = 0x2A91;
+	    break;
+	  case 0x2A93:
+	    *ch = 0x2A94;
+	    break;
+	  case 0x2A94:
+	    *ch = 0x2A93;
+	    break;
+	  case 0x2A95:
+	    *ch = 0x2A96;
+	    break;
+	  case 0x2A96:
+	    *ch = 0x2A95;
+	    break;
+	  case 0x2A97:
+	    *ch = 0x2A98;
+	    break;
+	  case 0x2A98:
+	    *ch = 0x2A97;
+	    break;
+	  case 0x2A99:
+	    *ch = 0x2A9A;
+	    break;
+	  case 0x2A9A:
+	    *ch = 0x2A99;
+	    break;
+	  case 0x2A9B:
+	    *ch = 0x2A9C;
+	    break;
+	  case 0x2A9C:
+	    *ch = 0x2A9B;
+	    break;
+	  case 0x2AA1:
+	    *ch = 0x2AA2;
+	    break;
+	  case 0x2AA2:
+	    *ch = 0x2AA1;
+	    break;
+	  case 0x2AA6:
+	    *ch = 0x2AA7;
+	    break;
+	  case 0x2AA7:
+	    *ch = 0x2AA6;
+	    break;
+	  case 0x2AA8:
+	    *ch = 0x2AA9;
+	    break;
+	  case 0x2AA9:
+	    *ch = 0x2AA8;
+	    break;
+	  case 0x2AAA:
+	    *ch = 0x2AAB;
+	    break;
+	  case 0x2AAB:
+	    *ch = 0x2AAA;
+	    break;
+	  case 0x2AAC:
+	    *ch = 0x2AAD;
+	    break;
+	  case 0x2AAD:
+	    *ch = 0x2AAC;
+	    break;
+	  case 0x2AAF:
+	    *ch = 0x2AB0;
+	    break;
+	  case 0x2AB0:
+	    *ch = 0x2AAF;
+	    break;
+	  case 0x2AB3:
+	    *ch = 0x2AB4;
+	    break;
+	  case 0x2AB4:
+	    *ch = 0x2AB3;
+	    break;
+	  case 0x2ABB:
+	    *ch = 0x2ABC;
+	    break;
+	  case 0x2ABC:
+	    *ch = 0x2ABB;
+	    break;
+	  case 0x2ABD:
+	    *ch = 0x2ABE;
+	    break;
+	  case 0x2ABE:
+	    *ch = 0x2ABD;
+	    break;
+	  case 0x2ABF:
+	    *ch = 0x2AC0;
+	    break;
+	  case 0x2AC0:
+	    *ch = 0x2ABF;
+	    break;
+	  case 0x2AC1:
+	    *ch = 0x2AC2;
+	    break;
+	  case 0x2AC2:
+	    *ch = 0x2AC1;
+	    break;
+	  case 0x2AC3:
+	    *ch = 0x2AC4;
+	    break;
+	  case 0x2AC4:
+	    *ch = 0x2AC3;
+	    break;
+	  case 0x2AC5:
+	    *ch = 0x2AC6;
+	    break;
+	  case 0x2AC6:
+	    *ch = 0x2AC5;
+	    break;
+	  case 0x2ACD:
+	    *ch = 0x2ACE;
+	    break;
+	  case 0x2ACE:
+	    *ch = 0x2ACD;
+	    break;
+	  case 0x2ACF:
+	    *ch = 0x2AD0;
+	    break;
+	  case 0x2AD0:
+	    *ch = 0x2ACF;
+	    break;
+	  case 0x2AD1:
+	    *ch = 0x2AD2;
+	    break;
+	  case 0x2AD2:
+	    *ch = 0x2AD1;
+	    break;
+	  case 0x2AD3:
+	    *ch = 0x2AD4;
+	    break;
+	  case 0x2AD4:
+	    *ch = 0x2AD3;
+	    break;
+	  case 0x2AD5:
+	    *ch = 0x2AD6;
+	    break;
+	  case 0x2AD6:
+	    *ch = 0x2AD5;
+	    break;
+	  case 0x2ADE:
+	    *ch = 0x22A6;
+	    break;
+	  case 0x2AE3:
+	    *ch = 0x22A9;
+	    break;
+	  case 0x2AE4:
+	    *ch = 0x22A8;
+	    break;
+	  case 0x2AE5:
+	    *ch = 0x22AB;
+	    break;
+	  case 0x2AEC:
+	    *ch = 0x2AED;
+	    break;
+	  case 0x2AED:
+	    *ch = 0x2AEC;
+	    break;
+	  case 0x2AF7:
+	    *ch = 0x2AF8;
+	    break;
+	  case 0x2AF8:
+	    *ch = 0x2AF7;
+	    break;
+	  case 0x2AF9:
+	    *ch = 0x2AFA;
+	    break;
+	  case 0x2AFA:
+	    *ch = 0x2AF9;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0x3000)
+    {
+	switch(*ch)
+	{
+	  case 0x3008:
+	    *ch = 0x3009;
+	    break;
+	  case 0x3009:
+	    *ch = 0x3008;
+	    break;
+	  case 0x300A:
+	    *ch = 0x300B;
+	    break;
+	  case 0x300B:
+	    *ch = 0x300A;
+	    break;
+	  case 0x300C:
+	    *ch = 0x300D;
+	    break;
+	  case 0x300D:
+	    *ch = 0x300C;
+	    break;
+	  case 0x300E:
+	    *ch = 0x300F;
+	    break;
+	  case 0x300F:
+	    *ch = 0x300E;
+	    break;
+	  case 0x3010:
+	    *ch = 0x3011;
+	    break;
+	  case 0x3011:
+	    *ch = 0x3010;
+	    break;
+	  case 0x3014:
+	    *ch = 0x3015;
+	    break;
+	  case 0x3015:
+	    *ch = 0x3014;
+	    break;
+	  case 0x3016:
+	    *ch = 0x3017;
+	    break;
+	  case 0x3017:
+	    *ch = 0x3016;
+	    break;
+	  case 0x3018:
+	    *ch = 0x3019;
+	    break;
+	  case 0x3019:
+	    *ch = 0x3018;
+	    break;
+	  case 0x301A:
+	    *ch = 0x301B;
+	    break;
+	  case 0x301B:
+	    *ch = 0x301A;
+	    break;
+	}
+    }
+    else if((*ch & 0xFF00) == 0xFF00)
+    {
+	switch(*ch)
+	{
+	  case 0xFF08:
+	    *ch = 0xFF09;
+	    break;
+	  case 0xFF09:
+	    *ch = 0xFF08;
+	    break;
+	  case 0xFF1C:
+	    *ch = 0xFF1E;
+	    break;
+	  case 0xFF1E:
+	    *ch = 0xFF1C;
+	    break;
+	  case 0xFF3B:
+	    *ch = 0xFF3D;
+	    break;
+	  case 0xFF3D:
+	    *ch = 0xFF3B;
+	    break;
+	  case 0xFF5B:
+	    *ch = 0xFF5D;
+	    break;
+	  case 0xFF5D:
+	    *ch = 0xFF5B;
+	    break;
+	  case 0xFF5F:
+	    *ch = 0xFF60;
+	    break;
+	  case 0xFF60:
+	    *ch = 0xFF5F;
+	    break;
+	  case 0xFF62:
+	    *ch = 0xFF63;
+	    break;
+	  case 0xFF63:
+	    *ch = 0xFF62;
+	    break;
+	}
+    }
+}

+ 456 - 0
putty/MINIBIDI.H

@@ -0,0 +1,456 @@
+/************************************************************************
+ * $Id: minibidi.h,v 1.1 2004/05/22 10:36:50 simon Exp $
+ *
+ * ------------
+ * Description:
+ * ------------
+ * This is an implemention of Unicode's Bidirectional Algorithm
+ * (known as UAX #9).
+ *
+ *   http://www.unicode.org/reports/tr9/
+ * 
+ * Author: Ahmad Khalifa
+ *
+ * -----------------
+ * Revision Details:    (Updated by Revision Control System)
+ * -----------------
+ *  $Date: 2004/05/22 10:36:50 $
+ *  $Author: simon $
+ *  $Revision: 1.1 $
+ *  $Source: /home/cvs/putty/minibidi.h,v $
+ *
+ * (www.arabeyes.org - under MIT license)
+ *
+ ************************************************************************/
+
+/*
+ * TODO:
+ * =====
+ * - work almost finished
+ * - Shaping Table to be expanded to include the whole range.
+ * - Ligature handling
+ */
+
+#include <stdlib.h>	/* definition of wchar_t*/
+
+#define LMASK	0x3F	/* Embedding Level mask */
+#define OMASK	0xC0	/* Override mask */
+#define OISL	0x80	/* Override is L */
+#define OISR	0x40	/* Override is R */
+
+/* Shaping Helpers */
+#define STYPE(xh) (((xh >= SHAPE_FIRST) && (xh <= SHAPE_LAST)) ? \
+shapetypes[xh-SHAPE_FIRST].type : SU) /*))*/
+#define SISOLATED(xh) (shapetypes[xh-SHAPE_FIRST].form_b)
+#define SFINAL(xh) xh+1
+#define SINITIAL(xh) xh+2
+#define SMEDIAL(ch) ch+3
+
+typedef struct bidi_char {
+    wchar_t origwc, wc;
+    unsigned short index;
+} bidi_char;
+
+/* function declarations */
+void flipThisRun(bidi_char *from, unsigned char* level, int max, int count);
+int findIndexOfRun(unsigned char* level , int start, int count, int tlevel);
+unsigned char getType(wchar_t ch);
+unsigned char setOverrideBits(unsigned char level, unsigned char override);
+unsigned char getPreviousLevel(unsigned char* level, int from);
+unsigned char leastGreaterOdd(unsigned char x);
+unsigned char leastGreaterEven(unsigned char x);
+unsigned char getRLE(wchar_t ch);
+int do_shape(bidi_char *line, bidi_char *to, int count);
+int do_bidi(bidi_char *line, int count);
+void doMirror(wchar_t* ch);
+
+/* character types */
+enum
+{
+   L,
+   LRE,
+   LRO,
+   R,
+   AL,
+   RLE,
+   RLO,
+   PDF,
+   EN,
+   ES,
+   ET,
+   AN,
+   CS,
+   NSM,
+   BN,
+   B,
+   S,
+   WS,
+   ON,
+};
+
+/* Shaping Types */
+enum
+{
+	SL, /* Left-Joining, doesnt exist in U+0600 - U+06FF */
+	SR, /* Right-Joining, ie has Isolated, Final */
+	SD, /* Dual-Joining, ie has Isolated, Final, Initial, Medial */
+	SU, /* Non-Joining */
+	SC  /* Join-Causing, like U+0640 (TATWEEL) */
+};
+
+typedef struct{
+	char type;
+	wchar_t form_b;
+} shape_node;
+
+/* Kept near the actual table, for verification. */
+#define SHAPE_FIRST 0x621
+#define SHAPE_LAST 0x64A
+
+const shape_node shapetypes[] = {
+/* index, Typ, Iso, Ligature Index*/
+/* 621 */ {SU, 0xFE80},
+/* 622 */ {SR, 0xFE81},
+/* 623 */ {SR, 0xFE83},
+/* 624 */ {SR, 0xFE85},
+/* 625 */ {SR, 0xFE87},
+/* 626 */ {SD, 0xFE89},
+/* 627 */ {SR, 0xFE8D},
+/* 628 */ {SD, 0xFE8F},
+/* 629 */ {SR, 0xFE93},
+/* 62A */ {SD, 0xFE95},
+/* 62B */ {SD, 0xFE99},
+/* 62C */ {SD, 0xFE9D},
+/* 62D */ {SD, 0xFEA1},
+/* 62E */ {SD, 0xFEA5},
+/* 62F */ {SR, 0xFEA9},
+/* 630 */ {SR, 0xFEAB},
+/* 631 */ {SR, 0xFEAD},
+/* 632 */ {SR, 0xFEAF},
+/* 633 */ {SD, 0xFEB1},
+/* 634 */ {SD, 0xFEB5},
+/* 635 */ {SD, 0xFEB9},
+/* 636 */ {SD, 0xFEBD},
+/* 637 */ {SD, 0xFEC1},
+/* 638 */ {SD, 0xFEC5},
+/* 639 */ {SD, 0xFEC9},
+/* 63A */ {SD, 0xFECD},
+/* 63B */ {SU, 0x0},
+/* 63C */ {SU, 0x0},
+/* 63D */ {SU, 0x0},
+/* 63E */ {SU, 0x0},
+/* 63F */ {SU, 0x0},
+/* 640 */ {SC, 0x0},
+/* 641 */ {SD, 0xFED1},
+/* 642 */ {SD, 0xFED5},
+/* 643 */ {SD, 0xFED9},
+/* 644 */ {SD, 0xFEDD},
+/* 645 */ {SD, 0xFEE1},
+/* 646 */ {SD, 0xFEE5},
+/* 647 */ {SD, 0xFEE9},
+/* 648 */ {SR, 0xFEED},
+/* 649 */ {SR, 0xFEEF}, /* SD */
+/* 64A */ {SD, 0xFEF1},
+};
+
+/*
+ * This describes the data byte and its frequency  
+ */
+typedef struct
+{
+   unsigned char f;
+   unsigned char d;
+}RLENode;
+
+
+/* This is an array of RLENodes, which is the
+ * Compressed unicode types table
+ */
+const unsigned char RLE_table[] =
+{
+   0x09, 0x10, 0x01, 0x0F, 0x01, 0x10, 0x01, 0x11,
+   0x01, 0x0F, 0x01, 0x0E, 0x0E, 0x0F, 0x03, 0x10,
+   0x01, 0x11, 0x01, 0x12, 0x02, 0x0A, 0x03, 0x12,
+   0x05, 0x0A, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x0C,
+   0x01, 0x09, 0x01, 0x08, 0x0A, 0x0C, 0x01, 0x12,
+   0x06, 0x00, 0x1A, 0x12, 0x06, 0x00, 0x1A, 0x12,
+   0x04, 0x0E, 0x06, 0x0F, 0x01, 0x0E, 0x1A, 0x0C,
+   0x01, 0x12, 0x01, 0x0A, 0x04, 0x12, 0x04, 0x00,
+   0x01, 0x12, 0x05, 0x0A, 0x02, 0x08, 0x02, 0x12,
+   0x01, 0x00, 0x01, 0x12, 0x03, 0x08, 0x01, 0x00,
+   0x01, 0x12, 0x05, 0x00, 0x17, 0x12, 0x01, 0x00,
+   0x1F, 0x12, 0x01, 0x00, 0xFF, 0x00, 0x2A, 0x12,
+   0x01, 0x00, 0x12, 0x12, 0x1C, 0x00, 0x5E, 0x12,
+   0x02, 0x00, 0x09, 0x12, 0x02, 0x00, 0x07, 0x12,
+   0x0E, 0x00, 0x02, 0x12, 0x0E, 0x00, 0x05, 0x12,
+   0x09, 0x00, 0x01, 0x12, 0x11, 0x0D, 0x50, 0x12,
+   0x10, 0x0D, 0x10, 0x12, 0x0A, 0x00, 0x01, 0x12,
+   0x0B, 0x00, 0x01, 0x12, 0x01, 0x00, 0x03, 0x12,
+   0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x14, 0x12,
+   0x01, 0x00, 0x2C, 0x12, 0x01, 0x00, 0x26, 0x12,
+   0x0A, 0x00, 0x83, 0x0D, 0x04, 0x12, 0x01, 0x0D,
+   0x02, 0x00, 0x45, 0x12, 0x01, 0x00, 0x26, 0x12,
+   0x02, 0x00, 0x02, 0x12, 0x06, 0x00, 0x10, 0x12,
+   0x21, 0x00, 0x26, 0x12, 0x02, 0x00, 0x07, 0x12,
+   0x01, 0x00, 0x27, 0x12, 0x01, 0x00, 0x01, 0x12,
+   0x07, 0x0D, 0x11, 0x12, 0x01, 0x0D, 0x17, 0x12,
+   0x01, 0x0D, 0x03, 0x03, 0x01, 0x0D, 0x01, 0x03,
+   0x01, 0x0D, 0x02, 0x03, 0x01, 0x0D, 0x01, 0x12,
+   0x0B, 0x03, 0x1B, 0x12, 0x05, 0x03, 0x05, 0x12,
+   0x17, 0x0C, 0x01, 0x12, 0x0E, 0x04, 0x01, 0x12,
+   0x03, 0x04, 0x01, 0x12, 0x01, 0x04, 0x1A, 0x12,
+   0x05, 0x04, 0x0B, 0x0D, 0x0B, 0x12, 0x0A, 0x0B,
+   0x0A, 0x0A, 0x01, 0x0B, 0x02, 0x04, 0x03, 0x0D,
+   0x01, 0x04, 0x65, 0x0D, 0x07, 0x04, 0x01, 0x0D,
+   0x07, 0x04, 0x02, 0x0D, 0x02, 0x12, 0x01, 0x0D,
+   0x04, 0x12, 0x02, 0x08, 0x0A, 0x04, 0x05, 0x12,
+   0x01, 0x04, 0x0E, 0x12, 0x01, 0x0E, 0x01, 0x04,
+   0x01, 0x0D, 0x01, 0x04, 0x1B, 0x12, 0x03, 0x0D,
+   0x1B, 0x12, 0x35, 0x04, 0x26, 0x0D, 0x0B, 0x04,
+   0x01, 0x12, 0xFF, 0x12, 0x50, 0x0D, 0x02, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x35, 0x12, 0x02, 0x0D,
+   0x01, 0x00, 0x04, 0x0D, 0x08, 0x00, 0x04, 0x0D,
+   0x01, 0x12, 0x02, 0x00, 0x01, 0x0D, 0x04, 0x12,
+   0x03, 0x00, 0x0A, 0x0D, 0x02, 0x00, 0x0D, 0x12,
+   0x10, 0x0D, 0x01, 0x00, 0x02, 0x12, 0x01, 0x00,
+   0x08, 0x12, 0x02, 0x00, 0x02, 0x12, 0x02, 0x00,
+   0x16, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x03, 0x00, 0x04, 0x12, 0x02, 0x0D,
+   0x01, 0x12, 0x01, 0x00, 0x03, 0x0D, 0x04, 0x12,
+   0x02, 0x00, 0x02, 0x12, 0x02, 0x00, 0x02, 0x0D,
+   0x01, 0x12, 0x09, 0x00, 0x01, 0x12, 0x04, 0x00,
+   0x02, 0x12, 0x01, 0x00, 0x03, 0x0D, 0x02, 0x12,
+   0x02, 0x00, 0x0C, 0x0A, 0x02, 0x00, 0x07, 0x12,
+   0x07, 0x0D, 0x01, 0x12, 0x02, 0x00, 0x06, 0x12,
+   0x04, 0x00, 0x02, 0x12, 0x02, 0x00, 0x16, 0x12,
+   0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x02, 0x12,
+   0x01, 0x00, 0x02, 0x12, 0x01, 0x00, 0x02, 0x12,
+   0x02, 0x0D, 0x01, 0x12, 0x01, 0x00, 0x03, 0x0D,
+   0x02, 0x12, 0x04, 0x0D, 0x02, 0x12, 0x02, 0x0D,
+   0x03, 0x12, 0x0B, 0x00, 0x04, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x07, 0x00, 0x0A, 0x0D, 0x02, 0x00,
+   0x03, 0x12, 0x0C, 0x0D, 0x02, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x03, 0x12, 0x01, 0x00, 0x16, 0x12,
+   0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x02, 0x12,
+   0x01, 0x00, 0x05, 0x12, 0x02, 0x0D, 0x01, 0x00,
+   0x04, 0x0D, 0x05, 0x12, 0x01, 0x0D, 0x02, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x02, 0x0D, 0x01, 0x12,
+   0x02, 0x00, 0x01, 0x12, 0x0F, 0x00, 0x01, 0x12,
+   0x05, 0x00, 0x0A, 0x12, 0x11, 0x0D, 0x01, 0x00,
+   0x02, 0x12, 0x01, 0x00, 0x08, 0x12, 0x02, 0x00,
+   0x02, 0x12, 0x02, 0x00, 0x16, 0x12, 0x01, 0x00,
+   0x07, 0x12, 0x01, 0x00, 0x02, 0x12, 0x02, 0x00,
+   0x04, 0x12, 0x02, 0x0D, 0x01, 0x00, 0x02, 0x0D,
+   0x01, 0x00, 0x01, 0x0D, 0x03, 0x12, 0x03, 0x00,
+   0x02, 0x12, 0x02, 0x00, 0x02, 0x0D, 0x01, 0x12,
+   0x08, 0x0D, 0x01, 0x00, 0x01, 0x12, 0x04, 0x00,
+   0x02, 0x12, 0x01, 0x00, 0x03, 0x12, 0x04, 0x00,
+   0x0B, 0x12, 0x11, 0x0D, 0x01, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x06, 0x12, 0x03, 0x00, 0x03, 0x12,
+   0x01, 0x00, 0x04, 0x12, 0x03, 0x00, 0x02, 0x12,
+   0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x02, 0x12,
+   0x03, 0x00, 0x02, 0x12, 0x03, 0x00, 0x03, 0x12,
+   0x03, 0x00, 0x08, 0x12, 0x01, 0x00, 0x03, 0x12,
+   0x04, 0x00, 0x02, 0x0D, 0x01, 0x00, 0x02, 0x12,
+   0x03, 0x00, 0x03, 0x12, 0x01, 0x00, 0x03, 0x0D,
+   0x01, 0x12, 0x09, 0x00, 0x01, 0x12, 0x0F, 0x00,
+   0x0C, 0x12, 0x0E, 0x00, 0x03, 0x12, 0x01, 0x00,
+   0x08, 0x12, 0x01, 0x00, 0x03, 0x12, 0x01, 0x00,
+   0x17, 0x12, 0x01, 0x00, 0x0A, 0x12, 0x01, 0x00,
+   0x05, 0x12, 0x04, 0x0D, 0x03, 0x00, 0x04, 0x12,
+   0x01, 0x0D, 0x03, 0x12, 0x01, 0x0D, 0x04, 0x12,
+   0x07, 0x0D, 0x02, 0x12, 0x09, 0x00, 0x02, 0x12,
+   0x04, 0x00, 0x0A, 0x12, 0x12, 0x00, 0x02, 0x12,
+   0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x03, 0x12,
+   0x01, 0x00, 0x17, 0x12, 0x01, 0x00, 0x0A, 0x12,
+   0x01, 0x00, 0x05, 0x12, 0x04, 0x00, 0x01, 0x0D,
+   0x01, 0x00, 0x05, 0x12, 0x01, 0x0D, 0x01, 0x00,
+   0x02, 0x12, 0x01, 0x00, 0x02, 0x0D, 0x02, 0x12,
+   0x07, 0x00, 0x02, 0x12, 0x07, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x02, 0x12, 0x04, 0x00, 0x0A, 0x12,
+   0x12, 0x00, 0x02, 0x12, 0x01, 0x00, 0x08, 0x12,
+   0x01, 0x00, 0x03, 0x12, 0x01, 0x00, 0x17, 0x12,
+   0x01, 0x00, 0x10, 0x12, 0x04, 0x00, 0x03, 0x0D,
+   0x03, 0x12, 0x02, 0x00, 0x03, 0x12, 0x01, 0x00,
+   0x03, 0x0D, 0x01, 0x12, 0x09, 0x00, 0x01, 0x12,
+   0x08, 0x00, 0x02, 0x12, 0x04, 0x00, 0x0A, 0x12,
+   0x12, 0x00, 0x02, 0x12, 0x01, 0x00, 0x12, 0x12,
+   0x03, 0x00, 0x18, 0x12, 0x01, 0x00, 0x09, 0x12,
+   0x01, 0x00, 0x01, 0x12, 0x02, 0x00, 0x07, 0x12,
+   0x03, 0x0D, 0x01, 0x12, 0x04, 0x00, 0x03, 0x0D,
+   0x03, 0x12, 0x01, 0x0D, 0x01, 0x12, 0x01, 0x00,
+   0x08, 0x12, 0x12, 0x00, 0x03, 0x12, 0x0C, 0x00,
+   0x30, 0x0D, 0x01, 0x00, 0x02, 0x0D, 0x07, 0x12,
+   0x04, 0x0A, 0x01, 0x00, 0x07, 0x0D, 0x08, 0x00,
+   0x0D, 0x12, 0x25, 0x00, 0x02, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x02, 0x00, 0x02, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x02, 0x00, 0x01, 0x12, 0x06, 0x00,
+   0x04, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x03, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x02, 0x00, 0x02, 0x12, 0x01, 0x00,
+   0x04, 0x0D, 0x01, 0x00, 0x02, 0x0D, 0x06, 0x12,
+   0x01, 0x0D, 0x02, 0x00, 0x01, 0x12, 0x02, 0x00,
+   0x05, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x0D,
+   0x06, 0x12, 0x02, 0x00, 0x0A, 0x12, 0x02, 0x00,
+   0x02, 0x12, 0x22, 0x00, 0x18, 0x0D, 0x02, 0x00,
+   0x1B, 0x0D, 0x01, 0x00, 0x01, 0x0D, 0x01, 0x00,
+   0x01, 0x0D, 0x01, 0x12, 0x04, 0x00, 0x0A, 0x12,
+   0x01, 0x00, 0x22, 0x12, 0x06, 0x0D, 0x0E, 0x00,
+   0x01, 0x0D, 0x05, 0x00, 0x01, 0x0D, 0x02, 0x00,
+   0x04, 0x12, 0x04, 0x0D, 0x08, 0x12, 0x01, 0x0D,
+   0x24, 0x12, 0x01, 0x00, 0x08, 0x0D, 0x01, 0x00,
+   0x06, 0x12, 0x02, 0x00, 0x01, 0x12, 0x30, 0x00,
+   0x22, 0x12, 0x01, 0x00, 0x05, 0x12, 0x01, 0x00,
+   0x02, 0x12, 0x01, 0x00, 0x01, 0x0D, 0x04, 0x00,
+   0x01, 0x0D, 0x01, 0x12, 0x03, 0x0D, 0x02, 0x00,
+   0x01, 0x0D, 0x01, 0x12, 0x06, 0x00, 0x18, 0x0D,
+   0x02, 0x12, 0x46, 0x00, 0x26, 0x12, 0x0A, 0x00,
+   0x29, 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0x00,
+   0x5A, 0x12, 0x05, 0x00, 0x44, 0x12, 0x05, 0x00,
+   0x52, 0x12, 0x06, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x3F, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x04, 0x12, 0x02, 0x00,
+   0x27, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x04, 0x12, 0x02, 0x00, 0x1F, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x04, 0x12, 0x02, 0x00,
+   0x07, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x07, 0x12, 0x01, 0x00, 0x17, 0x12, 0x01, 0x00,
+   0x1F, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x27, 0x12, 0x01, 0x00, 0x13, 0x12, 0x06, 0x00,
+   0x1C, 0x12, 0x23, 0x00, 0x55, 0x12, 0x0C, 0x00,
+   0xFF, 0x00, 0xFF, 0x00, 0x78, 0x12, 0x09, 0x11,
+   0x01, 0x00, 0x1A, 0x12, 0x05, 0x00, 0x51, 0x12,
+   0x0F, 0x00, 0x0D, 0x12, 0x01, 0x00, 0x04, 0x0D,
+   0x03, 0x12, 0x0B, 0x00, 0x12, 0x0D, 0x03, 0x00,
+   0x02, 0x12, 0x09, 0x00, 0x12, 0x0D, 0x02, 0x12,
+   0x0C, 0x00, 0x0D, 0x12, 0x01, 0x00, 0x03, 0x12,
+   0x01, 0x0D, 0x02, 0x12, 0x0C, 0x00, 0x37, 0x0D,
+   0x07, 0x00, 0x08, 0x0D, 0x01, 0x00, 0x02, 0x0D,
+   0x0B, 0x00, 0x07, 0x0A, 0x01, 0x00, 0x01, 0x12,
+   0x03, 0x00, 0x0A, 0x12, 0x21, 0x0D, 0x03, 0x0E,
+   0x01, 0x12, 0x01, 0x00, 0x0A, 0x12, 0x06, 0x00,
+   0x58, 0x12, 0x08, 0x00, 0x29, 0x0D, 0x01, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0x5B, 0x00, 0x9C, 0x12, 0x04, 0x00,
+   0x5A, 0x12, 0x06, 0x00, 0x16, 0x12, 0x02, 0x00,
+   0x06, 0x12, 0x02, 0x00, 0x26, 0x12, 0x02, 0x00,
+   0x06, 0x12, 0x02, 0x00, 0x08, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x01, 0x00, 0x1F, 0x12, 0x02, 0x00,
+   0x35, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0x03, 0x00, 0x03, 0x12, 0x01, 0x00,
+   0x07, 0x12, 0x03, 0x00, 0x04, 0x12, 0x02, 0x00,
+   0x06, 0x12, 0x04, 0x00, 0x0D, 0x12, 0x05, 0x00,
+   0x03, 0x12, 0x01, 0x00, 0x07, 0x12, 0x03, 0x11,
+   0x0B, 0x0E, 0x03, 0x00, 0x01, 0x03, 0x01, 0x12,
+   0x18, 0x11, 0x01, 0x0F, 0x01, 0x01, 0x01, 0x05,
+   0x01, 0x07, 0x01, 0x02, 0x01, 0x06, 0x01, 0x11,
+   0x01, 0x0A, 0x05, 0x12, 0x2A, 0x11, 0x01, 0x0E,
+   0x04, 0x12, 0x06, 0x0E, 0x06, 0x08, 0x01, 0x00,
+   0x01, 0x12, 0x02, 0x08, 0x06, 0x0A, 0x02, 0x12,
+   0x03, 0x00, 0x01, 0x08, 0x0A, 0x0A, 0x02, 0x12,
+   0x14, 0x0A, 0x12, 0x12, 0x1E, 0x0D, 0x1B, 0x12,
+   0x17, 0x00, 0x01, 0x12, 0x04, 0x00, 0x01, 0x12,
+   0x02, 0x00, 0x0A, 0x12, 0x01, 0x00, 0x01, 0x12,
+   0x03, 0x00, 0x05, 0x12, 0x06, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x01, 0x12,
+   0x01, 0x00, 0x04, 0x0A, 0x01, 0x00, 0x03, 0x12,
+   0x01, 0x00, 0x07, 0x12, 0x03, 0x00, 0x03, 0x12,
+   0x05, 0x00, 0x05, 0x12, 0x16, 0x00, 0x24, 0x12,
+   0x8E, 0x0A, 0x02, 0x12, 0xFF, 0x12, 0x23, 0x00,
+   0x45, 0x12, 0x1A, 0x00, 0x01, 0x12, 0xCA, 0x08,
+   0x3C, 0x00, 0x4E, 0x08, 0x01, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0x20, 0x11, 0x01, 0x12,
+   0x04, 0x00, 0x03, 0x12, 0x19, 0x00, 0x09, 0x0D,
+   0x06, 0x12, 0x01, 0x00, 0x05, 0x12, 0x02, 0x00,
+   0x05, 0x12, 0x04, 0x00, 0x56, 0x12, 0x02, 0x0D,
+   0x02, 0x12, 0x02, 0x00, 0x03, 0x12, 0x01, 0x00,
+   0x5A, 0x12, 0x01, 0x00, 0x04, 0x12, 0x05, 0x00,
+   0x28, 0x12, 0x04, 0x00, 0x5E, 0x12, 0x01, 0x00,
+   0x28, 0x12, 0x38, 0x00, 0x2D, 0x12, 0x03, 0x00,
+   0x24, 0x12, 0x1C, 0x00, 0x1C, 0x12, 0x03, 0x00,
+   0x32, 0x12, 0x0F, 0x00, 0x0C, 0x12, 0x04, 0x00,
+   0x2F, 0x12, 0x01, 0x00, 0x77, 0x12, 0x04, 0x00,
+   0x63, 0x12, 0x02, 0x00, 0x1F, 0x12, 0x01, 0x00,
+   0x01, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xCD, 0x00, 0x01, 0x12,
+   0x4A, 0x00, 0x01, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xF5, 0x00,
+   0x01, 0x12, 0x5A, 0x00, 0xFF, 0x00, 0xFF, 0x00,
+   0xFF, 0x00, 0xFF, 0x00, 0x91, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0x7A, 0x00, 0x01, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xCD, 0x00,
+   0x01, 0x12, 0x5C, 0x00, 0x01, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0x81, 0x00, 0x02, 0x12,
+   0x7E, 0x00, 0x02, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0x02, 0x00, 0x02, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
+   0xFF, 0x12, 0x17, 0x00, 0xFF, 0x00, 0x30, 0x12,
+   0x02, 0x00, 0x3B, 0x12, 0x95, 0x00, 0x07, 0x12,
+   0x0C, 0x00, 0x05, 0x12, 0x05, 0x03, 0x01, 0x0D,
+   0x01, 0x03, 0x0A, 0x0A, 0x01, 0x03, 0x0D, 0x12,
+   0x01, 0x03, 0x05, 0x12, 0x01, 0x03, 0x01, 0x12,
+   0x01, 0x03, 0x02, 0x12, 0x01, 0x03, 0x02, 0x12,
+   0x01, 0x03, 0x0A, 0x04, 0x62, 0x12, 0x21, 0x04,
+   0xFF, 0x04, 0x6C, 0x12, 0x12, 0x04, 0x40, 0x12,
+   0x02, 0x04, 0x36, 0x12, 0x28, 0x04, 0x0D, 0x12,
+   0x03, 0x0D, 0x10, 0x12, 0x10, 0x0D, 0x04, 0x12,
+   0x2C, 0x0C, 0x01, 0x12, 0x01, 0x0C, 0x01, 0x12,
+   0x02, 0x0C, 0x01, 0x12, 0x09, 0x0A, 0x01, 0x12,
+   0x02, 0x0A, 0x02, 0x12, 0x05, 0x0A, 0x02, 0x12,
+   0x05, 0x04, 0x05, 0x12, 0x01, 0x04, 0x87, 0x12,
+   0x02, 0x0E, 0x01, 0x12, 0x03, 0x0A, 0x03, 0x12,
+   0x05, 0x0A, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x0C,
+   0x01, 0x09, 0x01, 0x08, 0x0A, 0x0C, 0x01, 0x12,
+   0x06, 0x00, 0x1A, 0x12, 0x06, 0x00, 0x1A, 0x12,
+   0x0B, 0x00, 0x59, 0x12, 0x03, 0x00, 0x06, 0x12,
+   0x02, 0x00, 0x06, 0x12, 0x02, 0x00, 0x06, 0x12,
+   0x02, 0x00, 0x03, 0x12, 0x03, 0x0A, 0x02, 0x12,
+   0x03, 0x0A, 0x02, 0x12, 0x09, 0x00, 0x0E, 0x00,
+};

+ 4 - 0
putty/MISC.C

@@ -1,3 +1,7 @@
+/*
+ * Platform-independent routines shared between all PuTTY programs.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>

+ 788 - 742
putty/MKFILES.PL

@@ -1,13 +1,20 @@
 #!/usr/bin/env perl
 #
-# Makefile generator for PuTTY.
+# Cross-platform Makefile generator.
 #
 # Reads the file `Recipe' to determine the list of generated
 # executables and their component objects. Then reads the source
 # files to compute #include dependencies. Finally, writes out the
 # various target Makefiles.
 
+# PuTTY specifics which could still do with removing:
+#  - Mac makefile is not portabilised at all. Include directories
+#    are hardwired, and also the libraries are fixed. This is
+#    mainly because I was too scared to go anywhere near it.
+#  - sbcsgen.pl is still run at startup.
+
 use FileHandle;
+use Cwd;
 
 open IN, "Recipe" or do {
     # We want to deal correctly with being run from one of the
@@ -22,23 +29,38 @@ open IN, "Recipe" or do {
 # dependency analysis.
 eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."';
 
-@incdirs = ("", "charset/", "unix/", "mac/");
+@srcdirs = ("./");
 
+$divert = undef; # ref to scalar in which text is currently being put
 $help = ""; # list of newline-free lines of help text
+$project_name = "project"; # this is a good enough default
+%makefiles = (); # maps makefile types to output makefile pathnames
+%makefile_extra = (); # maps makefile types to extra Makefile text
 %programs = (); # maps prog name + type letter to listref of objects/resources
 %groups = (); # maps group name to listref of objects/resources
 
 while (<IN>) {
   # Skip comments (unless the comments belong, for example because
-  # they're part of the help text).
-  next if /^\s*#/ and !$in_help;
+  # they're part of a diversion).
+  next if /^\s*#/ and !defined $divert;
 
   chomp;
   split;
-  if ($_[0] eq "!begin" and $_[1] eq "help") { $in_help = 1; next; }
-  if ($_[0] eq "!end" and $in_help) { $in_help = 0; next; }
+  if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }
+  if ($_[0] eq "!end") { $divert = undef; next; }
+  if ($_[0] eq "!name") { $project_name = $_[1]; next; }
+  if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
+  if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
+  if ($_[0] eq "!begin") {
+      if (&mfval($_[1])) {
+	  $divert = \$makefile_extra{$_[1]};
+      } else {
+	  $divert = \$dummy;
+      }
+      next;
+  }
   # If we're gathering help text, keep doing so.
-  if ($in_help) { $help .= "$_\n"; next; }
+  if (defined $divert) { ${$divert} .= "$_\n"; next; }
   # Ignore blank lines.
   next if scalar @_ == 0;
 
@@ -69,7 +91,7 @@ while (<IN>) {
     if ($groups{$i}) {
       foreach $j (@{$groups{$i}}) { unshift @objs, $j; }
     } elsif (($i eq "[G]" or $i eq "[C]" or $i eq "[M]" or
-	      $i eq "[X]" or $i eq "[U]") and defined $prog) {
+              $i eq "[X]" or $i eq "[U]") and defined $prog) {
       $type = substr($i,1,1);
     } else {
       push @$listref, $i;
@@ -77,7 +99,7 @@ while (<IN>) {
   }
   if ($prog and $type) {
     die "multiple program entries for $prog [$type]\n"
-	if defined $programs{$prog . "," . $type};
+        if defined $programs{$prog . "," . $type};
     $programs{$prog . "," . $type} = $listref;
   }
   $lastlistref = $listref;
@@ -171,22 +193,47 @@ foreach $i (keys %depends) {
     foreach $j (@{$further{$file}}) {
       if ($dep{$j} != 1) {
         $dep{$j} = 1;
-	push @{$depends{$i}}, $j;
-	push @scanlist, $j;
+        push @{$depends{$i}}, $j;
+        push @scanlist, $j;
       }
     }
   }
 #  printf "%s: %s\n", $i, join ' ',@{$depends{$i}};
 }
 
+# Validation of input.
+
+sub mfval($) {
+    my ($type) = @_;
+    # Returns true if the argument is a known makefile type. Otherwise,
+    # prints a warning and returns false;
+    if (grep { $type eq $_ }
+	("vc","vcproj","cygwin","borland","lcc","gtk","mpw")) {
+	    return 1;
+	}
+    warn "$.:unknown makefile type '$type'\n";
+    return 0;
+}
+
 # Utility routines while writing out the Makefiles.
 
+sub dirpfx {
+    my ($path) = shift @_;
+    my ($sep) = shift @_;
+    my $ret = "", $i;
+    while (($i = index $path, $sep) >= 0) {
+	$path = substr $path, ($i + length $sep);
+	$ret .= "..$sep";
+    }
+    return $ret;
+}
+
 sub findfile {
   my ($name) = @_;
   my $dir, $i, $outdir = "";
   unless (defined $findfilecache{$name}) {
     $i = 0;
-    foreach $dir (@incdirs) {
+    foreach $dir (@srcdirs) {
       $outdir = $dir, $i++ if -f "$dir$name";
     }
     die "multiple instances of source file $name\n" if $i > 1;
@@ -291,763 +338,762 @@ sub manpages {
 
 # Now we're ready to output the actual Makefiles.
 
-##-- CygWin makefile
-open OUT, ">Makefile.cyg"; select OUT;
-print
-"# Makefile for PuTTY under cygwin.\n".
-"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
-"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
-# gcc command line option is -D not /D
-($_ = $help) =~ s/=\/D/=-D/gs;
-print $_;
-print
-"\n".
-"# You can define this path to point at your tools if you need to\n".
-"# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
-"# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
-"CC = \$(TOOLPATH)gcc\n".
-"RC = \$(TOOLPATH)windres\n".
-"# Uncomment the following two lines to compile under Winelib\n".
-"# CC = winegcc\n".
-"# RC = wrc\n".
-"# You may also need to tell windres where to find include files:\n".
-"# RCINC = --include-dir c:\\cygwin\\include\\\n".
-"\n".
-&splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
-  " -D_NO_OLDNAMES -DNO_MULTIMON -I.")."\n".
-"LDFLAGS = -mno-cygwin -s\n".
-&splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
-  " --define WINVER=0x0400 --define MINGW32_FIX=1")."\n".
-"\n".
-".SUFFIXES:\n".
-"\n".
-"%.o: %.c\n".
-"\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
-"\n".
-"%.res.o: %.rc\n".
-"\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n".
-"\n";
-print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
-print "\n\n";
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  $objstr = &objects($p, "X.o", "X.res.o", undef);
-  print &splitline($prog . ".exe: " . $objstr), "\n";
-  my $mw = $type eq "G" ? " -mwindows" : "";
-  $libstr = &objects($p, undef, undef, "-lX");
-  print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
-                   $objstr . " $libstr", 69), "\n\n";
-}
-foreach $d (&deps("X.o", "X.res.o", "", "/")) {
-  print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
-    "\n";
-}
-print
-"\n".
-"version.o: FORCE;\n".
-"# Hack to force version.o to be rebuilt always\n".
-"FORCE:\n".
-"\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) \$(VER) -c version.c\n".
-"clean:\n".
-"\trm -f *.o *.exe *.res.o\n".
-"\n";
-select STDOUT; close OUT;
+if (defined $makefiles{'cygwin'}) {
+    $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");
 
-##-- Borland makefile
-%stdlibs = (  # Borland provides many Win32 API libraries intrinsically
-  "advapi32" => 1,
-  "comctl32" => 1,
-  "comdlg32" => 1,
-  "gdi32" => 1,
-  "imm32" => 1,
-  "shell32" => 1,
-  "user32" => 1,
-  "winmm" => 1,
-  "winspool" => 1,
-  "wsock32" => 1,
-);	    
-open OUT, ">Makefile.bor"; select OUT;
-print
-"# Makefile for PuTTY under Borland C.\n".
-"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
-"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
-# bcc32 command line option is -D not /D
-($_ = $help) =~ s/=\/D/=-D/gs;
-print $_;
-print
-"\n".
-"# If you rename this file to `Makefile', you should change this line,\n".
-"# so that the .rsp files still depend on the correct makefile.\n".
-"MAKEFILE = Makefile.bor\n".
-"\n".
-"# C compilation flags\n".
-"CFLAGS = -D_WINDOWS -DWINVER=0x0401\n".
-"\n".
-"# Get include directory for resource compiler\n".
-"!if !\$d(BCB)\n".
-"BCB = \$(MAKEDIR)\\..\n".
-"!endif\n".
-"\n".
-".c.obj:\n".
-&splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT) \$(FWHACK)".
-  " \$(XFLAGS) \$(CFLAGS) /c \$*.c",69)."\n".
-".rc.res:\n".
-&splitline("\tbrcc32 \$(FWHACK) \$(RCFL) -i \$(BCB)\\include -r".
-  " -DNO_WINRESRC_H -DWIN32 -D_WIN32 -DWINVER=0x0401 \$*.rc",69)."\n".
-"\n";
-print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
-print "\n\n";
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  $objstr = &objects($p, "X.obj", "X.res", undef);
-  print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
-  my $ap = ($type eq "G") ? "-aa" : "-ap";
-  print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
-}
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  print $prog, ".rsp: \$(MAKEFILE)\n";
-  $objstr = &objects($p, "X.obj", undef, undef);
-  @objlist = split " ", $objstr;
-  @objlines = ("");
-  foreach $i (@objlist) {
-    if (length($objlines[$#objlines] . " $i") > 50) {
-      push @objlines, "";
+    ##-- CygWin makefile
+    open OUT, ">$makefiles{'cygwin'}"; select OUT;
+    print
+    "# Makefile for $project_name under cygwin.\n".
+    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # gcc command line option is -D not /D
+    ($_ = $help) =~ s/=\/D/=-D/gs;
+    print $_;
+    print
+    "\n".
+    "# You can define this path to point at your tools if you need to\n".
+    "# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".
+    "# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".
+    "CC = \$(TOOLPATH)gcc\n".
+    "RC = \$(TOOLPATH)windres\n".
+    "# Uncomment the following two lines to compile under Winelib\n".
+    "# CC = winegcc\n".
+    "# RC = wrc\n".
+    "# You may also need to tell windres where to find include files:\n".
+    "# RCINC = --include-dir c:\\cygwin\\include\\\n".
+    "\n".
+    &splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".
+      " -D_NO_OLDNAMES -DNO_MULTIMON " .
+	       (join " ", map {"-I$dirpfx$_"} @srcdirs)) .
+	       "\n".
+    "LDFLAGS = -mno-cygwin -s\n".
+    &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
+      " --define WINVER=0x0400 --define MINGW32_FIX=1")."\n".
+    "\n".
+    ".SUFFIXES:\n".
+    "\n".
+    "%.o: %.c\n".
+    "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
+    "\n".
+    "%.res.o: %.rc\n".
+    "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n".
+    "\n";
+    print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
+    print "\n\n";
+    foreach $p (&prognames("GC")) {
+      ($prog, $type) = split ",", $p;
+      $objstr = &objects($p, "X.o", "X.res.o", undef);
+      print &splitline($prog . ".exe: " . $objstr), "\n";
+      my $mw = $type eq "G" ? " -mwindows" : "";
+      $libstr = &objects($p, undef, undef, "-lX");
+      print &splitline("\t\$(CC)" . $mw . " \$(LDFLAGS) -o \$@ " .
+                       "-Wl,-Map,$prog.map " .
+                       $objstr . " $libstr", 69), "\n\n";
     }
-    $objlines[$#objlines] .= " $i";
-  }
-  $c0w = ($type eq "G") ? "c0w32" : "c0x32";
-  print "\techo $c0w + > $prog.rsp\n";
-  for ($i=0; $i<=$#objlines; $i++) {
-    $plus = ($i < $#objlines ? " +" : "");
-    print "\techo$objlines[$i]$plus >> $prog.rsp\n";
-  }
-  print "\techo $prog.exe >> $prog.rsp\n";
-  $objstr = &objects($p, "X.obj", "X.res", undef);
-  @libs = split " ", &objects($p, undef, undef, "X");
-  @libs = grep { !$stdlibs{$_} } @libs;
-  unshift @libs, "cw32", "import32";
-  $libstr = join ' ', @libs;
-  print "\techo nul,$libstr, >> $prog.rsp\n";
-  print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
-  print "\n";
-}
-foreach $d (&deps("X.obj", "X.res", "", "\\")) {
-  print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+    foreach $d (&deps("X.o", "X.res.o", $dirpfx, "/")) {
+      print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+        "\n";
+    }
+    print "\n";
+    print $makefile_extra{'cygwin'};
+    print "\nclean:\n".
+    "\trm -f *.o *.exe *.res.o *.map\n".
     "\n";
-}
-print
-"\n".
-"version.o: FORCE\n".
-"# Hack to force version.o to be rebuilt always\n".
-"FORCE:\n".
-"\tbcc32 \$(FWHACK) \$(VER) \$(CFLAGS) /c version.c\n\n".
-"clean:\n".
-"\t-del *.obj\n".
-"\t-del *.exe\n".
-"\t-del *.res\n".
-"\t-del *.pch\n".
-"\t-del *.aps\n".
-"\t-del *.il*\n".
-"\t-del *.pdb\n".
-"\t-del *.rsp\n".
-"\t-del *.tds\n".
-"\t-del *.\$\$\$\$\$\$\n";
-select STDOUT; close OUT;
+    select STDOUT; close OUT;
 
-##-- Visual C++ makefile
-open OUT, ">Makefile.vc"; select OUT;
-print
-"# Makefile for PuTTY under Visual C.\n".
-"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
-"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
-print $help;
-print
-"\n".
-"# If you rename this file to `Makefile', you should change this line,\n".
-"# so that the .rsp files still depend on the correct makefile.\n".
-"MAKEFILE = Makefile.vc\n".
-"\n".
-"# C compilation flags\n".
-"CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401\n".
-"LFLAGS = /incremental:no /fixed\n".
-"\n".
-".c.obj:\n".
-"\tcl \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) /c \$*.c\n".
-".rc.res:\n".
-"\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 -DWINVER=0x0400 \$*.rc\n".
-"\n";
-print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
-print "\n\n";
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  $objstr = &objects($p, "X.obj", "X.res", undef);
-  print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
-  print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
 }
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  print $prog, ".rsp: \$(MAKEFILE)\n";
-  $objstr = &objects($p, "X.obj", "X.res", "X.lib");
-  @objlist = split " ", $objstr;
-  @objlines = ("");
-  foreach $i (@objlist) {
-    if (length($objlines[$#objlines] . " $i") > 50) {
-      push @objlines, "";
+
+##-- Borland makefile
+if (defined $makefiles{'borland'}) {
+    $dirpfx = &dirpfx($makefiles{'borland'}, "\\");
+
+    %stdlibs = (  # Borland provides many Win32 API libraries intrinsically
+      "advapi32" => 1,
+      "comctl32" => 1,
+      "comdlg32" => 1,
+      "gdi32" => 1,
+      "imm32" => 1,
+      "shell32" => 1,
+      "user32" => 1,
+      "winmm" => 1,
+      "winspool" => 1,
+      "wsock32" => 1,
+    );
+    open OUT, ">$makefiles{'borland'}"; select OUT;
+    print
+    "# Makefile for $project_name under Borland C.\n".
+    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # bcc32 command line option is -D not /D
+    ($_ = $help) =~ s/=\/D/=-D/gs;
+    print $_;
+    print
+    "\n".
+    "# If you rename this file to `Makefile', you should change this line,\n".
+    "# so that the .rsp files still depend on the correct makefile.\n".
+    "MAKEFILE = Makefile.bor\n".
+    "\n".
+    "# C compilation flags\n".
+    "CFLAGS = -D_WINDOWS -DWINVER=0x0401\n".
+    "\n".
+    "# Get include directory for resource compiler\n".
+    "!if !\$d(BCB)\n".
+    "BCB = \$(MAKEDIR)\\..\n".
+    "!endif\n".
+    "\n".
+    ".c.obj:\n".
+    &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT) \$(FWHACK)".
+	       " \$(XFLAGS) \$(CFLAGS) ".
+	       (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+	       " /c \$*.c",69)."\n".
+    ".rc.res:\n".
+    &splitline("\tbrcc32 \$(FWHACK) \$(RCFL) -i \$(BCB)\\include -r".
+      " -DNO_WINRESRC_H -DWIN32 -D_WIN32 -DWINVER=0x0401 \$*.rc",69)."\n".
+    "\n";
+    print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
+    print "\n\n";
+    foreach $p (&prognames("GC")) {
+      ($prog, $type) = split ",", $p;
+      $objstr = &objects($p, "X.obj", "X.res", undef);
+      print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
+      my $ap = ($type eq "G") ? "-aa" : "-ap";
+      print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
     }
-    $objlines[$#objlines] .= " $i";
-  }
-  $subsys = ($type eq "G") ? "windows" : "console";
-  print "\techo /nologo /subsystem:$subsys > $prog.rsp\n";
-  for ($i=0; $i<=$#objlines; $i++) {
-    print "\techo$objlines[$i] >> $prog.rsp\n";
-  }
-  print "\n";
+    foreach $p (&prognames("GC")) {
+      ($prog, $type) = split ",", $p;
+      print $prog, ".rsp: \$(MAKEFILE)\n";
+      $objstr = &objects($p, "X.obj", undef, undef);
+      @objlist = split " ", $objstr;
+      @objlines = ("");
+      foreach $i (@objlist) {
+        if (length($objlines[$#objlines] . " $i") > 50) {
+          push @objlines, "";
+        }
+        $objlines[$#objlines] .= " $i";
+      }
+      $c0w = ($type eq "G") ? "c0w32" : "c0x32";
+      print "\techo $c0w + > $prog.rsp\n";
+      for ($i=0; $i<=$#objlines; $i++) {
+        $plus = ($i < $#objlines ? " +" : "");
+        print "\techo$objlines[$i]$plus >> $prog.rsp\n";
+      }
+      print "\techo $prog.exe >> $prog.rsp\n";
+      $objstr = &objects($p, "X.obj", "X.res", undef);
+      @libs = split " ", &objects($p, undef, undef, "X");
+      @libs = grep { !$stdlibs{$_} } @libs;
+      unshift @libs, "cw32", "import32";
+      $libstr = join ' ', @libs;
+      print "\techo nul,$libstr, >> $prog.rsp\n";
+      print "\techo " . &objects($p, undef, "X.res", undef) . " >> $prog.rsp\n";
+      print "\n";
+    }
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
+      print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+        "\n";
+    }
+    print "\n";
+    print $makefile_extra{'borland'};
+    print "\nclean:\n".
+    "\t-del *.obj\n".
+    "\t-del *.exe\n".
+    "\t-del *.res\n".
+    "\t-del *.pch\n".
+    "\t-del *.aps\n".
+    "\t-del *.il*\n".
+    "\t-del *.pdb\n".
+    "\t-del *.rsp\n".
+    "\t-del *.tds\n".
+    "\t-del *.\$\$\$\$\$\$\n";
+    select STDOUT; close OUT;
 }
-foreach $d (&deps("X.obj", "X.res", "", "\\")) {
-  print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+
+if (defined $makefiles{'vc'}) {
+    $dirpfx = &dirpfx($makefiles{'vc'}, "\\");
+
+    ##-- Visual C++ makefile
+    open OUT, ">$makefiles{'vc'}"; select OUT;
+    print
+      "# Makefile for $project_name under Visual C.\n".
+      "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+      "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    print $help;
+    print
+      "\n".
+      "# If you rename this file to `Makefile', you should change this line,\n".
+      "# so that the .rsp files still depend on the correct makefile.\n".
+      "MAKEFILE = Makefile.vc\n".
+      "\n".
+      "# C compilation flags\n".
+      "CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401\n".
+      "LFLAGS = /incremental:no /fixed\n".
+      "\n".
+      ".c.obj:\n".
+      "\tcl \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) /c \$*.c\n".
+      ".rc.res:\n".
+      "\trc \$(FWHACK) \$(RCFL) -r -DWIN32 -D_WIN32 -DWINVER=0x0400 \$*.rc\n".
       "\n";
+    print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
+    print "\n\n";
+    foreach $p (&prognames("GC")) {
+	($prog, $type) = split ",", $p;
+	$objstr = &objects($p, "X.obj", "X.res", undef);
+	print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
+	print "\tlink \$(LFLAGS) -out:$prog.exe -map:$prog.map \@$prog.rsp\n\n";
+    }
+    foreach $p (&prognames("GC")) {
+	($prog, $type) = split ",", $p;
+	print $prog, ".rsp: \$(MAKEFILE)\n";
+	$objstr = &objects($p, "X.obj", "X.res", "X.lib");
+	@objlist = split " ", $objstr;
+	@objlines = ("");
+	foreach $i (@objlist) {
+	    if (length($objlines[$#objlines] . " $i") > 50) {
+		push @objlines, "";
+	    }
+	    $objlines[$#objlines] .= " $i";
+	}
+	$subsys = ($type eq "G") ? "windows" : "console";
+	print "\techo /nologo /subsystem:$subsys > $prog.rsp\n";
+	for ($i=0; $i<=$#objlines; $i++) {
+	    print "\techo$objlines[$i] >> $prog.rsp\n";
+	}
+	print "\n";
+    }
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
+	print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+	  "\n";
+    }
+    print "\n";
+    print $makefile_extra{'vc'};
+    print "\nclean: tidy\n".
+      "\t-del *.exe\n\n".
+      "tidy:\n".
+      "\t-del *.obj\n".
+      "\t-del *.res\n".
+      "\t-del *.pch\n".
+      "\t-del *.aps\n".
+      "\t-del *.ilk\n".
+      "\t-del *.pdb\n".
+      "\t-del *.rsp\n".
+      "\t-del *.dsp\n".
+      "\t-del *.dsw\n".
+      "\t-del *.ncb\n".
+      "\t-del *.opt\n".
+      "\t-del *.plg\n".
+      "\t-del *.map\n".
+      "\t-del *.idb\n".
+      "\t-del debug.log\n";
+    select STDOUT; close OUT;
 }
-print
-"\n".
-"# Hack to force version.o to be rebuilt always\n".
-"version.obj: *.c *.h *.rc\n".
-"\tcl \$(FWHACK) \$(VER) \$(CFLAGS) /c version.c\n\n".
-"clean: tidy\n".
-"\t-del *.exe\n\n".
-"tidy:\n".
-"\t-del *.obj\n".
-"\t-del *.res\n".
-"\t-del *.pch\n".
-"\t-del *.aps\n".
-"\t-del *.ilk\n".
-"\t-del *.pdb\n".
-"\t-del *.rsp\n".
-"\t-del *.dsp\n".
-"\t-del *.dsw\n".
-"\t-del *.ncb\n".
-"\t-del *.opt\n".
-"\t-del *.plg\n".
-"\t-del *.map\n".
-"\t-del *.idb\n".
-"\t-del debug.log\n";
-select STDOUT; close OUT;
 
-##-- MSVC 6 Workspace and projects
-#
-# Note: All files created in this section are written in binary
-# mode, because although MSVC's command-line make can deal with
-# LF-only line endings, MSVC project files really _need_ to be
-# CRLF. Hence, in order for mkfiles.pl to generate usable project
-# files even when run from Unix, I make sure all files are binary
-# and explicitly write the CRLFs.
-#
-# Create directories if necessary
-mkdir 'MSVC'
-	if(! -d 'MSVC');
-chdir 'MSVC';
-@deps = &deps("X.obj", "X.res", "", "\\");
-%all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
-# Create the project files
-# Get names of all Windows projects (GUI and console)
-my @prognames = &prognames("GC");
-foreach $progname (@prognames) {
-	create_project(\%all_object_deps, $progname);
-}
-# Create the workspace file
-open OUT, ">putty.dsw"; binmode OUT; select OUT;
-print
-"Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
-"# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
-"\r\n".
-"###############################################################################\r\n".
-"\r\n";
-# List projects
-foreach $progname (@prognames) {
-  ($windows_project, $type) = split ",", $progname;
-	print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
-}
-print
-"\r\n".
-"Package=<5>\r\n".
-"{{{\r\n".
-"}}}\r\n".
-"\r\n".
-"Package=<4>\r\n".
-"{{{\r\n".
-"}}}\r\n".
-"\r\n".
-"###############################################################################\r\n".
-"\r\n".
-"Global:\r\n".
-"\r\n".
-"Package=<5>\r\n".
-"{{{\r\n".
-"}}}\r\n".
-"\r\n".
-"Package=<3>\r\n".
-"{{{\r\n".
-"}}}\r\n".
-"\r\n".
-"###############################################################################\r\n".
-"\r\n";
-select STDOUT; close OUT;
-chdir '..';
+if (defined $makefiles{'vcproj'}) {
 
-sub create_project {
-	my ($all_object_deps, $progname) = @_;
-	# Construct program's dependency info
-	%seen_objects = ();
-	%lib_files = ();
-	%source_files = ();
-	%header_files = ();
-	%resource_files = ();
-	@object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
-	foreach $object_file (@object_files) {
-		next if defined $seen_objects{$object_file};
-		$seen_objects{$object_file} = 1;
-		if($object_file =~ /\.lib$/io) {
-			$lib_files{$object_file} = 1;
-			next;
-		}
-		$object_deps = $all_object_deps{$object_file};
-		foreach $object_dep (@$object_deps) {
-			if($object_dep =~ /\.c$/io) {
-				$source_files{$object_dep} = 1;
-				next;
-			}
-			if($object_dep =~ /\.h$/io) {
-				$header_files{$object_dep} = 1;
-				next;
-			}
-			if($object_dep =~ /\.(rc|ico)$/io) {
-				$resource_files{$object_dep} = 1;
-				next;
-			}
+    $orig_dir = cwd;
+
+    ##-- MSVC 6 Workspace and projects
+    #
+    # Note: All files created in this section are written in binary
+    # mode, because although MSVC's command-line make can deal with
+    # LF-only line endings, MSVC project files really _need_ to be
+    # CRLF. Hence, in order for mkfiles.pl to generate usable project
+    # files even when run from Unix, I make sure all files are binary
+    # and explicitly write the CRLFs.
+    #
+    # Create directories if necessary
+    mkdir $makefiles{'vcproj'}
+        if(! -d $makefiles{'vcproj'});
+    chdir $makefiles{'vcproj'};
+    @deps = &deps("X.obj", "X.res", "", "\\");
+    %all_object_deps = map {$_->{obj} => $_->{deps}} @deps;
+    # Create the project files
+    # Get names of all Windows projects (GUI and console)
+    my @prognames = &prognames("GC");
+    foreach $progname (@prognames) {
+    	create_project(\%all_object_deps, $progname);
+    }
+    # Create the workspace file
+    open OUT, ">$project_name.dsw"; binmode OUT; select OUT;
+    print
+    "Microsoft Developer Studio Workspace File, Format Version 6.00\r\n".
+    "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r\n".
+    "\r\n".
+    "###############################################################################\r\n".
+    "\r\n";
+    # List projects
+    foreach $progname (@prognames) {
+      ($windows_project, $type) = split ",", $progname;
+    	print "Project: \"$windows_project\"=\".\\$windows_project\\$windows_project.dsp\" - Package Owner=<4>\r\n";
+    }
+    print
+    "\r\n".
+    "Package=<5>\r\n".
+    "{{{\r\n".
+    "}}}\r\n".
+    "\r\n".
+    "Package=<4>\r\n".
+    "{{{\r\n".
+    "}}}\r\n".
+    "\r\n".
+    "###############################################################################\r\n".
+    "\r\n".
+    "Global:\r\n".
+    "\r\n".
+    "Package=<5>\r\n".
+    "{{{\r\n".
+    "}}}\r\n".
+    "\r\n".
+    "Package=<3>\r\n".
+    "{{{\r\n".
+    "}}}\r\n".
+    "\r\n".
+    "###############################################################################\r\n".
+    "\r\n";
+    select STDOUT; close OUT;
+    chdir $orig_dir;
+
+    sub create_project {
+    	my ($all_object_deps, $progname) = @_;
+    	# Construct program's dependency info
+    	%seen_objects = ();
+    	%lib_files = ();
+    	%source_files = ();
+    	%header_files = ();
+    	%resource_files = ();
+    	@object_files = split " ", &objects($progname, "X.obj", "X.res", "X.lib");
+    	foreach $object_file (@object_files) {
+	    next if defined $seen_objects{$object_file};
+	    $seen_objects{$object_file} = 1;
+	    if($object_file =~ /\.lib$/io) {
+		$lib_files{$object_file} = 1;
+		next;
+	    }
+	    $object_deps = $all_object_deps{$object_file};
+	    foreach $object_dep (@$object_deps) {
+		if($object_dep =~ /\.c$/io) {
+		    $source_files{$object_dep} = 1;
+		    next;
 		}
-	}
-	$libs = join " ", sort keys %lib_files;
-	@source_files = sort keys %source_files;
-	@header_files = sort keys %header_files;
-	@resources = sort keys %resource_files;
-  ($windows_project, $type) = split ",", $progname;
-	mkdir $windows_project
-		if(! -d $windows_project);
-	chdir $windows_project;
-  $subsys = ($type eq "G") ? "windows" : "console";
-	open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
-	print
-	"# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
-	"# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
-	"# ** DO NOT EDIT **\r\n".
-	"\r\n".
-	"# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
-	"\r\n".
-	"CFG=$windows_project - Win32 Debug\r\n".
-	"!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
-	"!MESSAGE use the Export Makefile command and run\r\n".
-	"!MESSAGE \r\n".
-	"!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
-	"!MESSAGE \r\n".
-	"!MESSAGE You can specify a configuration when running NMAKE\r\n".
-	"!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
-	"!MESSAGE \r\n".
-	"!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
-	"!MESSAGE \r\n".
-	"!MESSAGE Possible choices for configuration are:\r\n".
-	"!MESSAGE \r\n".
-	"!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
-	"!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
-	"!MESSAGE \r\n".
-	"\r\n".
-	"# Begin Project\r\n".
-	"# PROP AllowPerConfigDependencies 0\r\n".
-	"# PROP Scc_ProjName \"\"\r\n".
-	"# PROP Scc_LocalPath \"\"\r\n".
-	"CPP=cl.exe\r\n".
-	"MTL=midl.exe\r\n".
-	"RSC=rc.exe\r\n".
-	"\r\n".
-	"!IF  \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
-	"\r\n".
-	"# PROP BASE Use_MFC 0\r\n".
-	"# PROP BASE Use_Debug_Libraries 0\r\n".
-	"# PROP BASE Output_Dir \"Release\"\r\n".
-	"# PROP BASE Intermediate_Dir \"Release\"\r\n".
-	"# PROP BASE Target_Dir \"\"\r\n".
-	"# PROP Use_MFC 0\r\n".
-	"# PROP Use_Debug_Libraries 0\r\n".
-	"# PROP Output_Dir \"Release\"\r\n".
-	"# PROP Intermediate_Dir \"Release\"\r\n".
-	"# PROP Ignore_Export_Lib 0\r\n".
-	"# PROP Target_Dir \"\"\r\n".
-	"# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
-	"# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
-	"# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
-	"# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
-	"# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
-	"# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
-	"BSC32=bscmake.exe\r\n".
-	"# ADD BASE BSC32 /nologo\r\n".
-	"# ADD BSC32 /nologo\r\n".
-	"LINK32=link.exe\r\n".
-	"# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /machine:I386\r\n".
-	"# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
-	"# SUBTRACT LINK32 /pdb:none\r\n".
-	"\r\n".
-	"!ELSEIF  \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
-	"\r\n".
-	"# PROP BASE Use_MFC 0\r\n".
-	"# PROP BASE Use_Debug_Libraries 1\r\n".
-	"# PROP BASE Output_Dir \"Debug\"\r\n".
-	"# PROP BASE Intermediate_Dir \"Debug\"\r\n".
-	"# PROP BASE Target_Dir \"\"\r\n".
-	"# PROP Use_MFC 0\r\n".
-	"# PROP Use_Debug_Libraries 1\r\n".
-	"# PROP Output_Dir \"Debug\"\r\n".
-	"# PROP Intermediate_Dir \"Debug\"\r\n".
-	"# PROP Ignore_Export_Lib 0\r\n".
-	"# PROP Target_Dir \"\"\r\n".
-	"# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
-	"# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
-	"# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
-	"# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
-	"# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
-	"# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
-	"BSC32=bscmake.exe\r\n".
-	"# ADD BASE BSC32 /nologo\r\n".
-	"# ADD BSC32 /nologo\r\n".
-	"LINK32=link.exe\r\n".
-	"# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
-	"# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
-	"# SUBTRACT LINK32 /pdb:none\r\n".
-	"\r\n".
-	"!ENDIF \r\n".
-	"\r\n".
-	"# Begin Target\r\n".
-	"\r\n".
-	"# Name \"$windows_project - Win32 Release\"\r\n".
-	"# Name \"$windows_project - Win32 Debug\"\r\n".
-	"# Begin Group \"Source Files\"\r\n".
-	"\r\n".
-	"# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
-	foreach $source_file (@source_files) {
-		print
-		"# Begin Source File\r\n".
-		"\r\n".
-		"SOURCE=..\\..\\$source_file\r\n";
-		if($source_file =~ /ssh\.c/io) {
-			# Disable 'Edit and continue' as Visual Studio can't handle the macros
-			print
-			"\r\n".
-			"!IF  \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
-			"\r\n".
-			"!ELSEIF  \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
-			"\r\n".
-			"# ADD CPP /Zi\r\n".
-			"\r\n".
-			"!ENDIF \r\n".
-			"\r\n";
+		if($object_dep =~ /\.h$/io) {
+		    $header_files{$object_dep} = 1;
+		    next;
 		}
-		print "# End Source File\r\n";
-	}
-	print
-	"# End Group\r\n".
-	"# Begin Group \"Header Files\"\r\n".
-	"\r\n".
-	"# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
-	foreach $header_file (@header_files) {
-		print
-		"# Begin Source File\r\n".
-		"\r\n".
-		"SOURCE=..\\..\\$header_file\r\n".
-		"# End Source File\r\n";
+		if($object_dep =~ /\.(rc|ico)$/io) {
+		    $resource_files{$object_dep} = 1;
+		    next;
 		}
-	print
-	"# End Group\r\n".
-	"# Begin Group \"Resource Files\"\r\n".
-	"\r\n".
-	"# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
-	foreach $resource_file (@resources) {
+	    }
+    	}
+    	$libs = join " ", sort keys %lib_files;
+    	@source_files = sort keys %source_files;
+    	@header_files = sort keys %header_files;
+    	@resources = sort keys %resource_files;
+	($windows_project, $type) = split ",", $progname;
+    	mkdir $windows_project
+	    if(! -d $windows_project);
+    	chdir $windows_project;
+	$subsys = ($type eq "G") ? "windows" : "console";
+    	open OUT, ">$windows_project.dsp"; binmode OUT; select OUT;
+    	print
+    	"# Microsoft Developer Studio Project File - Name=\"$windows_project\" - Package Owner=<4>\r\n".
+    	"# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n".
+    	"# ** DO NOT EDIT **\r\n".
+    	"\r\n".
+    	"# TARGTYPE \"Win32 (x86) Application\" 0x0101\r\n".
+    	"\r\n".
+    	"CFG=$windows_project - Win32 Debug\r\n".
+    	"!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n".
+    	"!MESSAGE use the Export Makefile command and run\r\n".
+    	"!MESSAGE \r\n".
+    	"!MESSAGE NMAKE /f \"$windows_project.mak\".\r\n".
+    	"!MESSAGE \r\n".
+    	"!MESSAGE You can specify a configuration when running NMAKE\r\n".
+    	"!MESSAGE by defining the macro CFG on the command line. For example:\r\n".
+    	"!MESSAGE \r\n".
+    	"!MESSAGE NMAKE /f \"$windows_project.mak\" CFG=\"$windows_project - Win32 Debug\"\r\n".
+    	"!MESSAGE \r\n".
+    	"!MESSAGE Possible choices for configuration are:\r\n".
+    	"!MESSAGE \r\n".
+    	"!MESSAGE \"$windows_project - Win32 Release\" (based on \"Win32 (x86) Application\")\r\n".
+    	"!MESSAGE \"$windows_project - Win32 Debug\" (based on \"Win32 (x86) Application\")\r\n".
+    	"!MESSAGE \r\n".
+    	"\r\n".
+    	"# Begin Project\r\n".
+    	"# PROP AllowPerConfigDependencies 0\r\n".
+    	"# PROP Scc_ProjName \"\"\r\n".
+    	"# PROP Scc_LocalPath \"\"\r\n".
+    	"CPP=cl.exe\r\n".
+    	"MTL=midl.exe\r\n".
+    	"RSC=rc.exe\r\n".
+    	"\r\n".
+    	"!IF  \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
+    	"\r\n".
+    	"# PROP BASE Use_MFC 0\r\n".
+    	"# PROP BASE Use_Debug_Libraries 0\r\n".
+    	"# PROP BASE Output_Dir \"Release\"\r\n".
+    	"# PROP BASE Intermediate_Dir \"Release\"\r\n".
+    	"# PROP BASE Target_Dir \"\"\r\n".
+    	"# PROP Use_MFC 0\r\n".
+    	"# PROP Use_Debug_Libraries 0\r\n".
+    	"# PROP Output_Dir \"Release\"\r\n".
+    	"# PROP Intermediate_Dir \"Release\"\r\n".
+    	"# PROP Ignore_Export_Lib 0\r\n".
+    	"# PROP Target_Dir \"\"\r\n".
+    	"# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
+    	"# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /c\r\n".
+    	"# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
+    	"# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\r\n".
+    	"# ADD BASE RSC /l 0x809 /d \"NDEBUG\"\r\n".
+    	"# ADD RSC /l 0x809 /d \"NDEBUG\"\r\n".
+    	"BSC32=bscmake.exe\r\n".
+    	"# ADD BASE BSC32 /nologo\r\n".
+    	"# ADD BSC32 /nologo\r\n".
+    	"LINK32=link.exe\r\n".
+    	"# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /machine:I386\r\n".
+    	"# ADD LINK32 $libs /nologo /subsystem:$subsys /machine:I386\r\n".
+    	"# SUBTRACT LINK32 /pdb:none\r\n".
+    	"\r\n".
+    	"!ELSEIF  \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
+    	"\r\n".
+    	"# PROP BASE Use_MFC 0\r\n".
+    	"# PROP BASE Use_Debug_Libraries 1\r\n".
+    	"# PROP BASE Output_Dir \"Debug\"\r\n".
+    	"# PROP BASE Intermediate_Dir \"Debug\"\r\n".
+    	"# PROP BASE Target_Dir \"\"\r\n".
+    	"# PROP Use_MFC 0\r\n".
+    	"# PROP Use_Debug_Libraries 1\r\n".
+    	"# PROP Output_Dir \"Debug\"\r\n".
+    	"# PROP Intermediate_Dir \"Debug\"\r\n".
+    	"# PROP Ignore_Export_Lib 0\r\n".
+    	"# PROP Target_Dir \"\"\r\n".
+    	"# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
+    	"# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" /YX /FD /GZ /c\r\n".
+    	"# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
+    	"# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\r\n".
+    	"# ADD BASE RSC /l 0x809 /d \"_DEBUG\"\r\n".
+    	"# ADD RSC /l 0x809 /d \"_DEBUG\"\r\n".
+    	"BSC32=bscmake.exe\r\n".
+    	"# ADD BASE BSC32 /nologo\r\n".
+    	"# ADD BSC32 /nologo\r\n".
+    	"LINK32=link.exe\r\n".
+    	"# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
+    	"# ADD LINK32 $libs /nologo /subsystem:$subsys /debug /machine:I386 /pdbtype:sept\r\n".
+    	"# SUBTRACT LINK32 /pdb:none\r\n".
+    	"\r\n".
+    	"!ENDIF \r\n".
+    	"\r\n".
+    	"# Begin Target\r\n".
+    	"\r\n".
+    	"# Name \"$windows_project - Win32 Release\"\r\n".
+    	"# Name \"$windows_project - Win32 Debug\"\r\n".
+    	"# Begin Group \"Source Files\"\r\n".
+    	"\r\n".
+    	"# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\r\n";
+    	foreach $source_file (@source_files) {
+	    print
+	      "# Begin Source File\r\n".
+	      "\r\n".
+	      "SOURCE=..\\..\\$source_file\r\n";
+	    if($source_file =~ /ssh\.c/io) {
+		# Disable 'Edit and continue' as Visual Studio can't handle the macros
 		print
-		"# Begin Source File\r\n".
-		"\r\n".
-		"SOURCE=..\\..\\$resource_file\r\n".
-		"# End Source File\r\n";
-		}
-	print
-	"# End Group\r\n".
-	"# End Target\r\n".
-	"# End Project\r\n";
-	select STDOUT; close OUT;
-	chdir '..';
+		  "\r\n".
+		  "!IF  \"\$(CFG)\" == \"$windows_project - Win32 Release\"\r\n".
+		  "\r\n".
+		  "!ELSEIF  \"\$(CFG)\" == \"$windows_project - Win32 Debug\"\r\n".
+		  "\r\n".
+		  "# ADD CPP /Zi\r\n".
+		  "\r\n".
+		  "!ENDIF \r\n".
+		  "\r\n";
+	    }
+	    print "# End Source File\r\n";
+    	}
+    	print
+    	"# End Group\r\n".
+    	"# Begin Group \"Header Files\"\r\n".
+    	"\r\n".
+    	"# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
+    	foreach $header_file (@header_files) {
+	    print
+	      "# Begin Source File\r\n".
+	      "\r\n".
+	      "SOURCE=..\\..\\$header_file\r\n".
+	      "# End Source File\r\n";
 	}
-
-##-- X/GTK/Unix makefile
-open OUT, ">unix/Makefile.gtk"; select OUT;
-print
-"# Makefile for PuTTY under X/GTK and Unix.\n".
-"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
-"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
-# gcc command line option is -D not /D
-($_ = $help) =~ s/=\/D/=-D/gs;
-print $_;
-print
-"\n".
-"# You can define this path to point at your tools if you need to\n".
-"# TOOLPATH = /opt/gcc/bin\n".
-"CC = \$(TOOLPATH)cc\n".
-"\n".
-&splitline("CFLAGS = -O2 -Wall -Werror -g -I. -I.. -I../charset `gtk-config --cflags`")."\n".
-"XLDFLAGS = `gtk-config --libs`\n".
-"ULDFLAGS =#\n".
-"INSTALL=install\n",
-"INSTALL_PROGRAM=\$(INSTALL)\n",
-"INSTALL_DATA=\$(INSTALL)\n",
-"prefix=/usr/local\n",
-"exec_prefix=\$(prefix)\n",
-"bindir=\$(exec_prefix)/bin\n",
-"mandir=\$(prefix)/man\n",
-"man1dir=\$(mandir)/man1\n",
-"\n".
-".SUFFIXES:\n".
-"\n".
-"%.o:\n".
-"\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
-"\n";
-print &splitline("all:" . join "", map { " $_" } &progrealnames("XU"));
-print "\n\n";
-foreach $p (&prognames("XU")) {
-  ($prog, $type) = split ",", $p;
-  $objstr = &objects($p, "X.o", undef, undef);
-  print &splitline($prog . ": " . $objstr), "\n";
-  $libstr = &objects($p, undef, undef, "-lX");
-  print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
-                   $objstr . " $libstr", 69), "\n\n";
-}
-foreach $d (&deps("X.o", undef, "../", "/")) {
-  print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
-      "\n";
+    	print
+    	"# End Group\r\n".
+    	"# Begin Group \"Resource Files\"\r\n".
+    	"\r\n".
+    	"# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\r\n";
+    	foreach $resource_file (@resources) {
+	    print
+	      "# Begin Source File\r\n".
+	      "\r\n".
+	      "SOURCE=..\\..\\$resource_file\r\n".
+	      "# End Source File\r\n";
+	}
+    	print
+    	"# End Group\r\n".
+    	"# End Target\r\n".
+    	"# End Project\r\n";
+    	select STDOUT; close OUT;
+    	chdir "..";
+    }
 }
-print
-"\n".
-"version.o: FORCE;\n".
-"# Hack to force version.o to be rebuilt always\n".
-"FORCE:\n".
-"\tif test -z \"\$(VER)\" && (cd ..; md5sum -c manifest); then \\\n".
-"\t\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) `cat ../version.def` -c ../version.c; \\\n".
-"\telse \\\n".
-"\t\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) \$(VER) -c ../version.c; \\\n".
-"\tfi\n".
-"clean:\n".
-"\trm -f *.o". (join "", map { " $_" } &progrealnames("XU")) . "\n".
-"\n",
-"install:\n",
-map("\t\$(INSTALL_PROGRAM) -m 755 $_ \$(DESTDIR)\$(bindir)/$_\n", &progrealnames("XU")),
-map("\t\$(INSTALL_DATA) -m 644 $_ \$(DESTDIR)\$(man1dir)/$_\n", &manpages("XU", "1")),
-"\n",
-"install-strip:\n",
-"\t\$(MAKE) install INSTALL_PROGRAM=\"\$(INSTALL_PROGRAM) -s\"\n",
-"\n";
-select STDOUT; close OUT;
-
-##-- MPW Makefile
-open OUT, ">mac/Makefile.mpw"; select OUT;
-print <<END;
-# Makefile for PuTTY under MPW.
-#
-# This file was created by `mkfiles.pl' from the `Recipe' file.
-# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.
-END
-# MPW command line option is -d not /D
-($_ = $help) =~ s/=\/D/=-d /gs;
-print $_;
-print <<END;
-
-ROptions     = `Echo "{VER}" | StreamEdit -e "1,\$ replace /=(\xc5)\xa81\xb0/ 'STR=\xb6\xb6\xb6\xb6\xb6"' \xa81 '\xb6\xb6\xb6\xb6\xb6"'"`
-
-C_68K = {C}
-C_CFM68K = {C}
-C_PPC = {PPCC}
-C_Carbon = {PPCC}
-
-# -w 35 disables "unused parameter" warnings
-COptions     = -i : -i :: -i ::charset -w 35 -w err -proto strict -ansi on \xb6
-	       -notOnce
-COptions_68K = {COptions} -model far -opt time
-# Enabling "-opt space" for CFM-68K gives me undefined references to
-# _\$LDIVT and _\$LMODT.
-COptions_CFM68K = {COptions} -model cfmSeg -opt time
-COptions_PPC = {COptions} -opt size -traceback
-COptions_Carbon = {COptions} -opt size -traceback -d TARGET_API_MAC_CARBON
-
-Link_68K = ILink
-Link_CFM68K = ILink
-Link_PPC = PPCLink
-Link_Carbon = PPCLink
-
-LinkOptions = -c 'pTTY'
-LinkOptions_68K = {LinkOptions} -br 68k -model far -compact
-LinkOptions_CFM68K = {LinkOptions} -br 020 -model cfmseg -compact
-LinkOptions_PPC = {LinkOptions}
-LinkOptions_Carbon = -m __appstart -w {LinkOptions}
-
-Libs_68K =	"{CLibraries}StdCLib.far.o" \xb6
-		"{Libraries}MacRuntime.o" \xb6
-		"{Libraries}MathLib.far.o" \xb6
-		"{Libraries}IntEnv.far.o" \xb6
-		"{Libraries}Interface.o" \xb6
-		"{Libraries}Navigation.far.o" \xb6
-		"{Libraries}OpenTransport.o" \xb6
-		"{Libraries}OpenTransportApp.o" \xb6
-		"{Libraries}OpenTptInet.o" \xb6
-		"{Libraries}UnicodeConverterLib.far.o"
-
-Libs_CFM =	"{SharedLibraries}InterfaceLib" \xb6
-		"{SharedLibraries}StdCLib" \xb6
-		"{SharedLibraries}AppearanceLib" \xb6
-			-weaklib AppearanceLib \xb6
-		"{SharedLibraries}NavigationLib" \xb6
-			-weaklib NavigationLib \xb6
-		"{SharedLibraries}TextCommon" \xb6
-			-weaklib TextCommon \xb6
-		"{SharedLibraries}UnicodeConverter" \xb6
-			-weaklib UnicodeConverter
 
-Libs_CFM68K =	{Libs_CFM} \xb6
-		"{CFM68KLibraries}NuMacRuntime.o"
+if (defined $makefiles{'gtk'}) {
+    $dirpfx = &dirpfx($makefiles{'gtk'}, "/");
 
-Libs_PPC =	{Libs_CFM} \xb6
-		"{SharedLibraries}ControlsLib" \xb6
-			-weaklib ControlsLib \xb6
-		"{SharedLibraries}WindowsLib" \xb6
-			-weaklib WindowsLib \xb6
-		"{SharedLibraries}OpenTransportLib" \xb6
-			-weaklib OTClientLib \xb6
-			-weaklib OTClientUtilLib \xb6
-		"{SharedLibraries}OpenTptInternetLib" \xb6
-			-weaklib OTInetClientLib \xb6
-		"{PPCLibraries}StdCRuntime.o" \xb6
-		"{PPCLibraries}PPCCRuntime.o" \xb6
-		"{PPCLibraries}CarbonAccessors.o" \xb6
-		"{PPCLibraries}OpenTransportAppPPC.o" \xb6
-		"{PPCLibraries}OpenTptInetPPC.o"
-
-Libs_Carbon =	"{PPCLibraries}CarbonStdCLib.o" \xb6
-		"{PPCLibraries}StdCRuntime.o" \xb6
-		"{PPCLibraries}PPCCRuntime.o" \xb6
-		"{SharedLibraries}CarbonLib" \xb6
-		"{SharedLibraries}StdCLib"
-
-END
-print &splitline("all \xc4 " . join(" ", &progrealnames("M")), undef, "\xb6");
-print "\n\n";
-foreach $p (&prognames("M")) {
-  ($prog, $type) = split ",", $p;
+    ##-- X/GTK/Unix makefile
+    open OUT, ">$makefiles{'gtk'}"; select OUT;
+    print
+    "# Makefile for $project_name under X/GTK and Unix.\n".
+    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # gcc command line option is -D not /D
+    ($_ = $help) =~ s/=\/D/=-D/gs;
+    print $_;
+    print
+    "\n".
+    "# You can define this path to point at your tools if you need to\n".
+    "# TOOLPATH = /opt/gcc/bin\n".
+    "CC = \$(TOOLPATH)cc\n".
+    "\n".
+    &splitline("CFLAGS = -O2 -Wall -Werror -g " .
+	       (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+	       " `gtk-config --cflags`")."\n".
+    "XLDFLAGS = `gtk-config --libs`\n".
+    "ULDFLAGS =#\n".
+    "INSTALL=install\n",
+    "INSTALL_PROGRAM=\$(INSTALL)\n",
+    "INSTALL_DATA=\$(INSTALL)\n",
+    "prefix=/usr/local\n",
+    "exec_prefix=\$(prefix)\n",
+    "bindir=\$(exec_prefix)/bin\n",
+    "mandir=\$(prefix)/man\n",
+    "man1dir=\$(mandir)/man1\n",
+    "\n".
+    ".SUFFIXES:\n".
+    "\n".
+    "%.o:\n".
+    "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
+    "\n";
+    print &splitline("all:" . join "", map { " $_" } &progrealnames("XU"));
+    print "\n\n";
+    foreach $p (&prognames("XU")) {
+      ($prog, $type) = split ",", $p;
+      $objstr = &objects($p, "X.o", undef, undef);
+      print &splitline($prog . ": " . $objstr), "\n";
+      $libstr = &objects($p, undef, undef, "-lX");
+      print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
+                       $objstr . " $libstr", 69), "\n\n";
+    }
+    foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
+      print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+          "\n";
+    }
+    print "\n";
+    print $makefile_extra{'gtk'};
+    print "\nclean:\n".
+    "\trm -f *.o". (join "", map { " $_" } &progrealnames("XU")) . "\n";
+    select STDOUT; close OUT;
+}
 
-  print &splitline("$prog \xc4 $prog.68k $prog.ppc $prog.carbon",
-		   undef, "\xb6"), "\n\n";
+if (defined $makefiles{'mpw'}) {
+    ##-- MPW Makefile
+    open OUT, ">$makefiles{'mpw'}"; select OUT;
+    print
+    "# Makefile for $project_name under MPW.\n#\n".
+    "# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # MPW command line option is -d not /D
+    ($_ = $help) =~ s/=\/D/=-d /gs;
+    print $_;
+    print "\n\n".
+    "ROptions     = `Echo \"{VER}\" | StreamEdit -e \"1,\$ replace /=(\xc5)\xa81\xb0/ 'STR=\xb6\xb6\xb6\xb6\xb6\"' \xa81 '\xb6\xb6\xb6\xb6\xb6\"'\"`".
+    "\n".
+    "C_68K = {C}\n".
+    "C_CFM68K = {C}\n".
+    "C_PPC = {PPCC}\n".
+    "C_Carbon = {PPCC}\n".
+    "\n".
+    "# -w 35 disables \"unused parameter\" warnings\n".
+    "COptions     = -i : -i :: -i ::charset -w 35 -w err -proto strict -ansi on \xb6\n".
+    "	       -notOnce\n".
+    "COptions_68K = {COptions} -model far -opt time\n".
+    "# Enabling \"-opt space\" for CFM-68K gives me undefined references to\n".
+    "# _\$LDIVT and _\$LMODT.\n".
+    "COptions_CFM68K = {COptions} -model cfmSeg -opt time\n".
+    "COptions_PPC = {COptions} -opt size -traceback\n".
+    "COptions_Carbon = {COptions} -opt size -traceback -d TARGET_API_MAC_CARBON\n".
+    "\n".
+    "Link_68K = ILink\n".
+    "Link_CFM68K = ILink\n".
+    "Link_PPC = PPCLink\n".
+    "Link_Carbon = PPCLink\n".
+    "\n".
+    "LinkOptions = -c 'pTTY'\n".
+    "LinkOptions_68K = {LinkOptions} -br 68k -model far -compact\n".
+    "LinkOptions_CFM68K = {LinkOptions} -br 020 -model cfmseg -compact\n".
+    "LinkOptions_PPC = {LinkOptions}\n".
+    "LinkOptions_Carbon = -m __appstart -w {LinkOptions}\n".
+    "\n".
+    "Libs_68K =	\"{CLibraries}StdCLib.far.o\" \xb6\n".
+    "		\"{Libraries}MacRuntime.o\" \xb6\n".
+    "		\"{Libraries}MathLib.far.o\" \xb6\n".
+    "		\"{Libraries}IntEnv.far.o\" \xb6\n".
+    "		\"{Libraries}Interface.o\" \xb6\n".
+    "		\"{Libraries}Navigation.far.o\" \xb6\n".
+    "		\"{Libraries}OpenTransport.o\" \xb6\n".
+    "		\"{Libraries}OpenTransportApp.o\" \xb6\n".
+    "		\"{Libraries}OpenTptInet.o\" \xb6\n".
+    "		\"{Libraries}UnicodeConverterLib.far.o\"\n".
+    "\n".
+    "Libs_CFM =	\"{SharedLibraries}InterfaceLib\" \xb6\n".
+    "		\"{SharedLibraries}StdCLib\" \xb6\n".
+    "		\"{SharedLibraries}AppearanceLib\" \xb6\n".
+    "			-weaklib AppearanceLib \xb6\n".
+    "		\"{SharedLibraries}NavigationLib\" \xb6\n".
+    "			-weaklib NavigationLib \xb6\n".
+    "		\"{SharedLibraries}TextCommon\" \xb6\n".
+    "			-weaklib TextCommon \xb6\n".
+    "		\"{SharedLibraries}UnicodeConverter\" \xb6\n".
+    "			-weaklib UnicodeConverter\n".
+    "\n".
+    "Libs_CFM68K =	{Libs_CFM} \xb6\n".
+    "		\"{CFM68KLibraries}NuMacRuntime.o\"\n".
+    "\n".
+    "Libs_PPC =	{Libs_CFM} \xb6\n".
+    "		\"{SharedLibraries}ControlsLib\" \xb6\n".
+    "			-weaklib ControlsLib \xb6\n".
+    "		\"{SharedLibraries}WindowsLib\" \xb6\n".
+    "			-weaklib WindowsLib \xb6\n".
+    "		\"{SharedLibraries}OpenTransportLib\" \xb6\n".
+    "			-weaklib OTClientLib \xb6\n".
+    "			-weaklib OTClientUtilLib \xb6\n".
+    "		\"{SharedLibraries}OpenTptInternetLib\" \xb6\n".
+    "			-weaklib OTInetClientLib \xb6\n".
+    "		\"{PPCLibraries}StdCRuntime.o\" \xb6\n".
+    "		\"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
+    "		\"{PPCLibraries}CarbonAccessors.o\" \xb6\n".
+    "		\"{PPCLibraries}OpenTransportAppPPC.o\" \xb6\n".
+    "		\"{PPCLibraries}OpenTptInetPPC.o\"\n".
+    "\n".
+    "Libs_Carbon =	\"{PPCLibraries}CarbonStdCLib.o\" \xb6\n".
+    "		\"{PPCLibraries}StdCRuntime.o\" \xb6\n".
+    "		\"{PPCLibraries}PPCCRuntime.o\" \xb6\n".
+    "		\"{SharedLibraries}CarbonLib\" \xb6\n".
+    "		\"{SharedLibraries}StdCLib\"\n".
+    "\n";
+    print &splitline("all \xc4 " . join(" ", &progrealnames("M")), undef, "\xb6");
+    print "\n\n";
+    foreach $p (&prognames("M")) {
+      ($prog, $type) = split ",", $p;
 
-  $rsrc = &objects($p, "", "X.rsrc", undef);
+      print &splitline("$prog \xc4 $prog.68k $prog.ppc $prog.carbon",
+    		   undef, "\xb6"), "\n\n";
 
-  foreach $arch (qw(68K CFM68K PPC Carbon)) {
-      $objstr = &objects($p, "X.\L$arch\E.o", "", undef);
-      print &splitline("$prog.\L$arch\E \xc4 $objstr $rsrc", undef, "\xb6");
-      print "\n";
-      print &splitline("\tDuplicate -y $rsrc {Targ}", 69, "\xb6"), "\n";
-      print &splitline("\t{Link_$arch} -o {Targ} -fragname $prog " .
-		       "{LinkOptions_$arch} " .
-		       $objstr . " {Libs_$arch}", 69, "\xb6"), "\n";
-      print &splitline("\tSetFile -a BMi {Targ}", 69, "\xb6"), "\n\n";
-  }
+      $rsrc = &objects($p, "", "X.rsrc", undef);
 
-}
-foreach $d (&deps("", "X.rsrc", "::", ":")) {
-  next unless $d->{obj};
-  print &splitline(sprintf("%s \xc4 %s", $d->{obj}, join " ", @{$d->{deps}}),
-		   undef, "\xb6"), "\n";
-  print "\tRez ", $d->{deps}->[0], " -o {Targ} {ROptions}\n\n";
-}
-foreach $arch (qw(68K CFM68K)) {
-    foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
-	 next unless $d->{obj};
-	print &splitline(sprintf("%s \xc4 %s", $d->{obj},
-				 join " ", @{$d->{deps}}),
-			 undef, "\xb6"), "\n";
-	 print "\t{C_$arch} ", $d->{deps}->[0],
-	       " -o {Targ} {COptions_$arch}\n\n";
-     }
-}
-foreach $arch (qw(PPC Carbon)) {
-    foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
-	 next unless $d->{obj};
-	print &splitline(sprintf("%s \xc4 %s", $d->{obj},
-				 join " ", @{$d->{deps}}),
-			 undef, "\xb6"), "\n";
-	 # The odd stuff here seems to stop afpd getting confused.
-	 print "\techo -n > {Targ}\n";
-	 print "\tsetfile -t XCOF {Targ}\n";
-	 print "\t{C_$arch} ", $d->{deps}->[0],
-	       " -o {Targ} {COptions_$arch}\n\n";
-     }
-}
-select STDOUT; close OUT;
+      foreach $arch (qw(68K CFM68K PPC Carbon)) {
+          $objstr = &objects($p, "X.\L$arch\E.o", "", undef);
+          print &splitline("$prog.\L$arch\E \xc4 $objstr $rsrc", undef, "\xb6");
+          print "\n";
+          print &splitline("\tDuplicate -y $rsrc {Targ}", 69, "\xb6"), "\n";
+          print &splitline("\t{Link_$arch} -o {Targ} -fragname $prog " .
+    		       "{LinkOptions_$arch} " .
+    		       $objstr . " {Libs_$arch}", 69, "\xb6"), "\n";
+          print &splitline("\tSetFile -a BMi {Targ}", 69, "\xb6"), "\n\n";
+      }
 
-##-- lcc makefile
-open OUT, ">Makefile.lcc"; select OUT;
-print
-"# Makefile for PuTTY under lcc.\n".
-"#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
-"# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
-# lcc command line option is -D not /D
-($_ = $help) =~ s/=\/D/=-D/gs;
-print $_;
-print
-"\n".
-"# If you rename this file to `Makefile', you should change this line,\n".
-"# so that the .rsp files still depend on the correct makefile.\n".
-"MAKEFILE = Makefile.lcc\n".
-"\n".
-"# C compilation flags\n".
-"CFLAGS = -D_WINDOWS\n".
-"\n".
-"# Get include directory for resource compiler\n".
-"\n".
-".c.obj:\n".
-&splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK)".
-  " \$(XFLAGS) \$(CFLAGS)  \$*.c",69)."\n".
-".rc.res:\n".
-&splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n".
-"\n";
-print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
-print "\n\n";
-foreach $p (&prognames("GC")) {
-  ($prog, $type) = split ",", $p;
-  $objstr = &objects($p, "X.obj", "X.res", undef);
-  print &splitline("$prog.exe: " . $objstr ), "\n";
-  $subsystemtype = undef;
-  if ($prog eq "pageant" || $prog eq "putty" ||$prog eq "puttygen" || $prog eq "puttytel") { 
-	$subsystemtype = "-subsystem  windows";	}
-  my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
-  print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
-  print "\n\n";
+    }
+    foreach $d (&deps("", "X.rsrc", "::", ":")) {
+      next unless $d->{obj};
+      print &splitline(sprintf("%s \xc4 %s", $d->{obj}, join " ", @{$d->{deps}}),
+    		   undef, "\xb6"), "\n";
+      print "\tRez ", $d->{deps}->[0], " -o {Targ} {ROptions}\n\n";
+    }
+    foreach $arch (qw(68K CFM68K)) {
+        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
+    	 next unless $d->{obj};
+    	print &splitline(sprintf("%s \xc4 %s", $d->{obj},
+    				 join " ", @{$d->{deps}}),
+    			 undef, "\xb6"), "\n";
+    	 print "\t{C_$arch} ", $d->{deps}->[0],
+    	       " -o {Targ} {COptions_$arch}\n\n";
+         }
+    }
+    foreach $arch (qw(PPC Carbon)) {
+        foreach $d (&deps("X.\L$arch\E.o", "", "::", ":")) {
+    	 next unless $d->{obj};
+    	print &splitline(sprintf("%s \xc4 %s", $d->{obj},
+    				 join " ", @{$d->{deps}}),
+    			 undef, "\xb6"), "\n";
+    	 # The odd stuff here seems to stop afpd getting confused.
+    	 print "\techo -n > {Targ}\n";
+    	 print "\tsetfile -t XCOF {Targ}\n";
+    	 print "\t{C_$arch} ", $d->{deps}->[0],
+    	       " -o {Targ} {COptions_$arch}\n\n";
+         }
+    }
+    select STDOUT; close OUT;
 }
 
+if (defined $makefiles{'lcc'}) {
+    $dirpfx = &dirpfx($makefiles{'lcc'}, "\\");
 
-foreach $d (&deps("X.obj", "X.res", "", "\\")) {
-  print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+    ##-- lcc makefile
+    open OUT, ">$makefiles{'lcc'}"; select OUT;
+    print
+    "# Makefile for $project_name under lcc.\n".
+    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # lcc command line option is -D not /D
+    ($_ = $help) =~ s/=\/D/=-D/gs;
+    print $_;
+    print
+    "\n".
+    "# If you rename this file to `Makefile', you should change this line,\n".
+    "# so that the .rsp files still depend on the correct makefile.\n".
+    "MAKEFILE = Makefile.lcc\n".
+    "\n".
+    "# C compilation flags\n".
+    "CFLAGS = -D_WINDOWS " .
+      (join " ", map {"-I$dirpfx$_"} @srcdirs) .
+      "\n".
+    "\n".
+    "# Get include directory for resource compiler\n".
+    "\n".
+    ".c.obj:\n".
+    &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK)".
+      " \$(XFLAGS) \$(CFLAGS)  \$*.c",69)."\n".
+    ".rc.res:\n".
+    &splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n".
     "\n";
-}
-print
-"\n".
-"version.o: FORCE\n".
-"# Hack to force version.o to be rebuilt always\n".
-"FORCE:\n".
-"\tlcc \$(FWHACK) \$(VER) \$(CFLAGS) /c version.c\n\n".
-"clean:\n".
-"\t-del *.obj\n".
-"\t-del *.exe\n".
-"\t-del *.res\n";
+    print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("GC"));
+    print "\n\n";
+    foreach $p (&prognames("GC")) {
+      ($prog, $type) = split ",", $p;
+      $objstr = &objects($p, "X.obj", "X.res", undef);
+      print &splitline("$prog.exe: " . $objstr ), "\n";
+      $subsystemtype = undef;
+      if ($type eq "G") { $subsystemtype = "-subsystem  windows"; }
+      my $libss = "shell32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib";
+      print &splitline("\tlcclnk $subsystemtype -o $prog.exe $objstr $libss");
+      print "\n\n";
+    }
 
-select STDOUT; close OUT;
+    foreach $d (&deps("X.obj", "X.res", $dirpfx, "\\")) {
+      print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+        "\n";
+    }
+    print "\n";
+    print $makefile_extra{'lcc'};
+    print "\nclean:\n".
+    "\t-del *.obj\n".
+    "\t-del *.exe\n".
+    "\t-del *.res\n";
 
+    select STDOUT; close OUT;
+}

+ 1 - 0
putty/MKUNXARC.SH

@@ -24,6 +24,7 @@ case "$1" in
 esac
 
 perl mkfiles.pl
+(cd doc && make -s)
 
 relver=`cat LATEST.VER`
 arcname="putty$arcsuffix"

+ 5 - 5
putty/NETWORK.H

@@ -79,8 +79,8 @@ struct plug_function_table {
  * responsibility for freeing it */
 Socket new_connection(SockAddr addr, char *hostname,
 		      int port, int privport,
-		      int oobinline, int nodelay, Plug plug,
-		      const Config *cfg);
+		      int oobinline, int nodelay, int keepalive,
+		      Plug plug, const Config *cfg);
 Socket new_listener(char *srcaddr, int port, Plug plug, int local_host_only,
 		    const Config *cfg);
 SockAddr name_lookup(char *host, int port, char **canonicalname,
@@ -90,8 +90,8 @@ SockAddr name_lookup(char *host, int port, char **canonicalname,
 /* (same caveat about addr as new_connection()) */
 Socket platform_new_connection(SockAddr addr, char *hostname,
 			       int port, int privport,
-			       int oobinline, int nodelay, Plug plug,
-			       const Config *cfg);
+			       int oobinline, int nodelay, int keepalive,
+			       Plug plug, const Config *cfg);
 
 /* socket functions */
 
@@ -111,7 +111,7 @@ void sk_addr_free(SockAddr addr);
 /* NB, control of 'addr' is passed via sk_new, which takes responsibility
  * for freeing it, as for new_connection() */
 Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
-	      int nodelay, Plug p);
+	      int nodelay, int keepalive, Plug p);
 
 Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only);
 

+ 0 - 26
putty/NOISE.C

@@ -9,12 +9,6 @@
 #include "ssh.h"
 #include "storage.h"
 
-/*
- * GetSystemPowerStatus function.
- */
-typedef BOOL(WINAPI * gsps_t) (LPSYSTEM_POWER_STATUS);
-static gsps_t gsps;
-
 /*
  * This function is called once, at PuTTY startup, and will do some
  * seriously silly things like listing directories and getting disk
@@ -26,7 +20,6 @@ void noise_get_heavy(void (*func) (void *, int))
     HANDLE srch;
     WIN32_FIND_DATA finddata;
     char winpath[MAX_PATH + 3];
-    HMODULE mod;
 
     GetWindowsDirectory(winpath, sizeof(winpath));
     strcat(winpath, "\\*");
@@ -41,12 +34,6 @@ void noise_get_heavy(void (*func) (void *, int))
     read_random_seed(func);
     /* Update the seed immediately, in case another instance uses it. */
     random_save_seed();
-
-    gsps = NULL;
-    mod = GetModuleHandle("KERNEL32");
-    if (mod) {
-	gsps = (gsps_t) GetProcAddress(mod, "GetSystemPowerStatus");
-    }
 }
 
 void random_save_seed(void)
@@ -71,21 +58,12 @@ void noise_get_light(void (*func) (void *, int))
     SYSTEMTIME systime;
     DWORD adjust[2];
     BOOL rubbish;
-    SYSTEM_POWER_STATUS pwrstat;
 
     GetSystemTime(&systime);
     func(&systime, sizeof(systime));
 
     GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);
     func(&adjust, sizeof(adjust));
-
-    /*
-     * Call GetSystemPowerStatus if present.
-     */
-    if (gsps) {
-	if (gsps(&pwrstat))
-	    func(&pwrstat, sizeof(pwrstat));
-    }
 }
 
 /*
@@ -144,7 +122,3 @@ void noise_ultralight(unsigned long data)
     if (QueryPerformanceCounter(&perftime))
 	random_add_noise(&perftime, sizeof(perftime));
 }
-
-
-
-

+ 189 - 31
putty/PAGEANT.C

@@ -119,8 +119,8 @@ static gsi_fn_t getsecurityinfo;
  */
 static void *make_keylist1(int *length);
 static void *make_keylist2(int *length);
-static void *get_keylist1(void);
-static void *get_keylist2(void);
+static void *get_keylist1(int *length);
+static void *get_keylist2(int *length);
 
 /*
  * We need this to link with the RSA code, because rsaencrypt()
@@ -414,7 +414,7 @@ static void add_keyfile(Filename filename)
     {
 	void *blob;
 	unsigned char *keylist, *p;
-	int i, nkeys, bloblen;
+	int i, nkeys, bloblen, keylistlen;
 
 	if (type == SSH_KEYTYPE_SSH1) {
 	    if (!rsakey_pubblob(&filename, &blob, &bloblen, NULL)) {
@@ -422,7 +422,7 @@ static void add_keyfile(Filename filename)
 			   MB_OK | MB_ICONERROR);
 		return;
 	    }
-	    keylist = get_keylist1();
+	    keylist = get_keylist1(&keylistlen);
 	} else {
 	    unsigned char *blob2;
 	    blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen, NULL);
@@ -438,11 +438,17 @@ static void add_keyfile(Filename filename)
 	    sfree(blob);
 	    blob = blob2;
 
-	    keylist = get_keylist2();
+	    keylist = get_keylist2(&keylistlen);
 	}
 	if (keylist) {
+	    if (keylistlen < 4) {
+		MessageBox(NULL, "Received broken key list?!", APPNAME,
+			   MB_OK | MB_ICONERROR);
+		return;
+	    }
 	    nkeys = GET_32BIT(keylist);
 	    p = keylist + 4;
+	    keylistlen -= 4;
 
 	    for (i = 0; i < nkeys; i++) {
 		if (!memcmp(blob, p, bloblen)) {
@@ -452,12 +458,48 @@ static void add_keyfile(Filename filename)
 		    return;
 		}
 		/* Now skip over public blob */
-		if (type == SSH_KEYTYPE_SSH1)
-		    p += rsa_public_blob_len(p);
-		else
-		    p += 4 + GET_32BIT(p);
+		if (type == SSH_KEYTYPE_SSH1) {
+		    int n = rsa_public_blob_len(p, keylistlen);
+		    if (n < 0) {
+			MessageBox(NULL, "Received broken key list?!", APPNAME,
+				   MB_OK | MB_ICONERROR);
+			return;
+		    }
+		    p += n;
+		    keylistlen -= n;
+		} else {
+		    int n;
+		    if (keylistlen < 4) {
+			MessageBox(NULL, "Received broken key list?!", APPNAME,
+				   MB_OK | MB_ICONERROR);
+			return;
+		    }
+		    n = 4 + GET_32BIT(p);
+		    if (keylistlen < n) {
+			MessageBox(NULL, "Received broken key list?!", APPNAME,
+				   MB_OK | MB_ICONERROR);
+			return;
+		    }
+		    p += n;
+		    keylistlen -= n;
+		}
 		/* Now skip over comment field */
-		p += 4 + GET_32BIT(p);
+		{
+		    int n;
+		    if (keylistlen < 4) {
+			MessageBox(NULL, "Received broken key list?!", APPNAME,
+				   MB_OK | MB_ICONERROR);
+			return;
+		    }
+		    n = 4 + GET_32BIT(p);
+		    if (keylistlen < n) {
+			MessageBox(NULL, "Received broken key list?!", APPNAME,
+				   MB_OK | MB_ICONERROR);
+			return;
+		    }
+		    p += n;
+		    keylistlen -= n;
+		}
 	    }
 
 	    sfree(keylist);
@@ -608,8 +650,8 @@ static void add_keyfile(Filename filename)
 						keybloblen);
 	    PUT_32BIT(request + reqlen, clen);
 	    memcpy(request + reqlen + 4, skey->comment, clen);
-	    PUT_32BIT(request, reqlen - 4);
 	    reqlen += clen + 4;
+	    PUT_32BIT(request, reqlen - 4);
 
 	    ret = agent_query(request, reqlen, &vresponse, &resplen,
 			      NULL, NULL);
@@ -731,7 +773,7 @@ static void *make_keylist2(int *length)
  * calling make_keylist1 (if that's us) or sending a message to the
  * primary Pageant (if it's not).
  */
-static void *get_keylist1(void)
+static void *get_keylist1(int *length)
 {
     void *ret;
 
@@ -751,8 +793,11 @@ static void *get_keylist1(void)
 	ret = snewn(resplen-5, unsigned char);
 	memcpy(ret, response+5, resplen-5);
 	sfree(response);
+
+	if (length)
+	    *length = resplen-5;
     } else {
-	ret = make_keylist1(NULL);
+	ret = make_keylist1(length);
     }
     return ret;
 }
@@ -762,7 +807,7 @@ static void *get_keylist1(void)
  * calling make_keylist2 (if that's us) or sending a message to the
  * primary Pageant (if it's not).
  */
-static void *get_keylist2(void)
+static void *get_keylist2(int *length)
 {
     void *ret;
 
@@ -783,8 +828,11 @@ static void *get_keylist2(void)
 	ret = snewn(resplen-5, unsigned char);
 	memcpy(ret, response+5, resplen-5);
 	sfree(response);
+
+	if (length)
+	    *length = resplen-5;
     } else {
-	ret = make_keylist2(NULL);
+	ret = make_keylist2(length);
     }
     return ret;
 }
@@ -796,11 +844,19 @@ static void answer_msg(void *msg)
 {
     unsigned char *p = msg;
     unsigned char *ret = msg;
+    unsigned char *msgend;
     int type;
 
+    /*
+     * Get the message length.
+     */
+    msgend = p + 4 + GET_32BIT(p);
+
     /*
      * Get the message type.
      */
+    if (msgend < p+5)
+	goto failure;
     type = p[4];
 
     p += 5;
@@ -857,12 +913,28 @@ static void answer_msg(void *msg)
 	    int i, len;
 
 	    p += 4;
-	    p += ssh1_read_bignum(p, &reqkey.exponent);
-	    p += ssh1_read_bignum(p, &reqkey.modulus);
-	    p += ssh1_read_bignum(p, &challenge);
+	    i = ssh1_read_bignum(p, msgend - p, &reqkey.exponent);
+	    if (i < 0)
+		goto failure;
+	    p += i;
+	    i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus);
+	    if (i < 0)
+		goto failure;
+	    p += i;
+	    i = ssh1_read_bignum(p, msgend - p, &challenge);
+	    if (i < 0)
+		goto failure;
+	    p += i;
+	    if (msgend < p+16) {
+		freebn(reqkey.exponent);
+		freebn(reqkey.modulus);
+		freebn(challenge);
+		goto failure;
+	    }
 	    memcpy(response_source + 32, p, 16);
 	    p += 16;
-	    if (GET_32BIT(p) != 1 ||
+	    if (msgend < p+4 ||
+		GET_32BIT(p) != 1 ||
 		(key = find234(rsakeys, &reqkey, NULL)) == NULL) {
 		freebn(reqkey.exponent);
 		freebn(reqkey.modulus);
@@ -904,12 +976,20 @@ static void answer_msg(void *msg)
 	    unsigned char *data, *signature;
 	    int datalen, siglen, len;
 
+	    if (msgend < p+4)
+		goto failure;
 	    b.len = GET_32BIT(p);
 	    p += 4;
+	    if (msgend < p+b.len)
+		goto failure;
 	    b.blob = p;
 	    p += b.len;
+	    if (msgend < p+4)
+		goto failure;
 	    datalen = GET_32BIT(p);
 	    p += 4;
+	    if (msgend < p+datalen)
+		goto failure;
 	    data = p;
 	    key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm);
 	    if (!key)
@@ -931,15 +1011,64 @@ static void answer_msg(void *msg)
 	{
 	    struct RSAKey *key;
 	    char *comment;
-            int commentlen;
+            int n, commentlen;
+
 	    key = snew(struct RSAKey);
 	    memset(key, 0, sizeof(struct RSAKey));
-	    p += makekey(p, key, NULL, 1);
-	    p += makeprivate(p, key);
-	    p += ssh1_read_bignum(p, &key->iqmp);	/* p^-1 mod q */
-	    p += ssh1_read_bignum(p, &key->p);	/* p */
-	    p += ssh1_read_bignum(p, &key->q);	/* q */
+
+	    n = makekey(p, msgend - p, key, NULL, 1);
+	    if (n < 0) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+	    p += n;
+
+	    n = makeprivate(p, msgend - p, key);
+	    if (n < 0) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+	    p += n;
+
+	    n = ssh1_read_bignum(p, msgend - p, &key->iqmp);  /* p^-1 mod q */
+	    if (n < 0) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+	    p += n;
+
+	    n = ssh1_read_bignum(p, msgend - p, &key->p);  /* p */
+	    if (n < 0) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+	    p += n;
+
+	    n = ssh1_read_bignum(p, msgend - p, &key->q);  /* q */
+	    if (n < 0) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+	    p += n;
+
+	    if (msgend < p+4) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
             commentlen = GET_32BIT(p);
+
+	    if (msgend < p+commentlen) {
+		freersakey(key);
+		sfree(key);
+		goto failure;
+	    }
+
 	    comment = snewn(commentlen+1, char);
 	    if (comment) {
 		memcpy(comment, p + 4, commentlen);
@@ -968,12 +1097,17 @@ static void answer_msg(void *msg)
 	    int alglen, commlen;
 	    int bloblen;
 
-	    key = snew(struct ssh2_userkey);
 
+	    if (msgend < p+4)
+		goto failure;
 	    alglen = GET_32BIT(p);
 	    p += 4;
+	    if (msgend < p+alglen)
+		goto failure;
 	    alg = p;
 	    p += alglen;
+
+	    key = snew(struct ssh2_userkey);
 	    /* Add further algorithm names here. */
 	    if (alglen == 7 && !memcmp(alg, "ssh-rsa", 7))
 		key->alg = &ssh_rsa;
@@ -984,18 +1118,32 @@ static void answer_msg(void *msg)
 		goto failure;
 	    }
 
-	    bloblen =
-		GET_32BIT((unsigned char *) msg) - (p -
-						    (unsigned char *) msg -
-						    4);
+	    bloblen = msgend - p;
 	    key->data = key->alg->openssh_createkey(&p, &bloblen);
 	    if (!key->data) {
 		sfree(key);
 		goto failure;
 	    }
+
+	    /*
+	     * p has been advanced by openssh_createkey, but
+	     * certainly not _beyond_ the end of the buffer.
+	     */
+	    assert(p <= msgend);
+
+	    if (msgend < p+4) {
+		key->alg->freekey(key->data);
+		sfree(key);
+		goto failure;
+	    }
 	    commlen = GET_32BIT(p);
 	    p += 4;
 
+	    if (msgend < p+commlen) {
+		key->alg->freekey(key->data);
+		sfree(key);
+		goto failure;
+	    }
 	    comment = snewn(commlen + 1, char);
 	    if (comment) {
 		memcpy(comment, p, commlen);
@@ -1023,8 +1171,12 @@ static void answer_msg(void *msg)
 	 */
 	{
 	    struct RSAKey reqkey, *key;
+	    int n;
+
+	    n = makekey(p, msgend - p, &reqkey, NULL, 0);
+	    if (n < 0)
+		goto failure;
 
-	    p += makekey(p, &reqkey, NULL, 0);
 	    key = find234(rsakeys, &reqkey, NULL);
 	    freebn(reqkey.exponent);
 	    freebn(reqkey.modulus);
@@ -1049,10 +1201,16 @@ static void answer_msg(void *msg)
 	    struct ssh2_userkey *key;
 	    struct blob b;
 
+	    if (msgend < p+4)
+		goto failure;
 	    b.len = GET_32BIT(p);
 	    p += 4;
+
+	    if (msgend < p+b.len)
+		goto failure;
 	    b.blob = p;
 	    p += b.len;
+
 	    key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm);
 	    if (!key)
 		goto failure;

+ 15 - 3
putty/PLINK.C

@@ -1,5 +1,5 @@
 /*
- * PLink - a command-line (stdin/stdout) variant of PuTTY.
+ * PLink - a Windows command-line (stdin/stdout) variant of PuTTY.
  */
 
 #include <stdio.h>
@@ -210,6 +210,7 @@ static void usage(void)
     printf("Usage: plink [options] [user@]host [command]\n");
     printf("       (\"host\" can also be a PuTTY saved session name)\n");
     printf("Options:\n");
+    printf("  -V        print version information\n");
     printf("  -v        show verbose messages\n");
     printf("  -load sessname  Load settings from saved session\n");
     printf("  -ssh -telnet -rlogin -raw\n");
@@ -236,6 +237,12 @@ static void usage(void)
     exit(1);
 }
 
+static void version(void)
+{
+    printf("plink: %s\n", ver);
+    exit(1);
+}
+
 char *do_select(SOCKET skt, int startup)
 {
     int events;
@@ -288,6 +295,7 @@ int main(int argc, char **argv)
      * Process the command line.
      */
     do_defaults(NULL, &cfg);
+    loaded_session = FALSE;
     default_protocol = cfg.protocol;
     default_port = cfg.port;
     errors = 0;
@@ -326,6 +334,8 @@ int main(int argc, char **argv)
 	    } else if (!strcmp(p, "-s")) {
 		/* Save status to write to cfg later. */
 		use_subsystem = 1;
+	    } else if (!strcmp(p, "-V")) {
+                version();
 	    } else {
 		fprintf(stderr, "plink: unknown option \"%s\"\n", p);
 		errors = 1;
@@ -400,13 +410,15 @@ int main(int argc, char **argv)
 			 */
 			Config cfg2;
 			do_defaults(p, &cfg2);
-			if (cfg2.host[0] == '\0') {
+			if (loaded_session || cfg2.host[0] == '\0') {
 			    /* No settings for this host; use defaults */
+			    /* (or session was already loaded with -load) */
 			    strncpy(cfg.host, p, sizeof(cfg.host) - 1);
 			    cfg.host[sizeof(cfg.host) - 1] = '\0';
 			    cfg.port = default_port;
 			} else {
 			    cfg = cfg2;
+			    /* Ick: patch up internal pointer after copy */
 			    cfg.remote_cmd_ptr = cfg.remote_cmd;
 			}
 		    } else {
@@ -555,7 +567,7 @@ int main(int argc, char **argv)
 	    (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);
 
 	error = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port,
-			   &realhost, nodelay);
+			   &realhost, nodelay, cfg.tcp_keepalives);
 	if (error) {
 	    fprintf(stderr, "Unable to open connection:\n%s", error);
 	    return 1;

+ 1 - 1
putty/PORTFWD.C

@@ -390,7 +390,7 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port,
     pr->dynamic = 0;
 
     pr->s = *s = new_connection(addr, dummy_realhost, port,
-				0, 1, 0, (Plug) pr, cfg);
+				0, 1, 0, 0, (Plug) pr, cfg);
     if ((err = sk_socket_error(*s)) != NULL) {
 	sfree(pr);
 	return err;

+ 2 - 2
putty/PPROXY.C

@@ -10,8 +10,8 @@
 
 Socket platform_new_connection(SockAddr addr, char *hostname,
 			       int port, int privport,
-			       int oobinline, int nodelay, Plug plug,
-			       const Config *cfg)
+			       int oobinline, int nodelay, int keepalive,
+			       Plug plug, const Config *cfg)
 {
     return NULL;
 }

+ 6 - 5
putty/PROXY.C

@@ -356,8 +356,8 @@ SockAddr name_lookup(char *host, int port, char **canonicalname,
 
 Socket new_connection(SockAddr addr, char *hostname,
 		      int port, int privport,
-		      int oobinline, int nodelay, Plug plug,
-		      const Config *cfg)
+		      int oobinline, int nodelay, int keepalive,
+		      Plug plug, const Config *cfg)
 {
     static const struct socket_function_table socket_fn_table = {
 	sk_proxy_plug,
@@ -388,7 +388,8 @@ Socket new_connection(SockAddr addr, char *hostname,
 	Socket sret;
 
 	if ((sret = platform_new_connection(addr, hostname, port, privport,
-					    oobinline, nodelay, plug, cfg)) !=
+					    oobinline, nodelay, keepalive,
+					    plug, cfg)) !=
 	    NULL)
 	    return sret;
 
@@ -444,7 +445,7 @@ Socket new_connection(SockAddr addr, char *hostname,
 	 */
 	ret->sub_socket = sk_new(proxy_addr, cfg->proxy_port,
 				 privport, oobinline,
-				 nodelay, (Plug) pplug);
+				 nodelay, keepalive, (Plug) pplug);
 	if (sk_socket_error(ret->sub_socket) != NULL)
 	    return (Socket) ret;
 
@@ -456,7 +457,7 @@ Socket new_connection(SockAddr addr, char *hostname,
     }
 
     /* no proxy, so just return the direct socket */
-    return sk_new(addr, port, privport, oobinline, nodelay, plug);
+    return sk_new(addr, port, privport, oobinline, nodelay, keepalive, plug);
 }
 
 Socket new_listener(char *srcaddr, int port, Plug plug, int local_host_only,

+ 56 - 11
putty/PSFTP.C

@@ -1,5 +1,5 @@
 /*
- * psftp.c: front end for PSFTP.
+ * psftp.c: (platform-independent) front end for PSFTP.
  */
 
 #include <stdio.h>
@@ -1765,7 +1765,7 @@ static void usage(void)
 {
     printf("PuTTY Secure File Transfer (SFTP) client\n");
     printf("%s\n", ver);
-    printf("Usage: psftp [options] user@host\n");
+    printf("Usage: psftp [options] [user@]host\n");
     printf("Options:\n");
     printf("  -b file   use specified batchfile\n");
     printf("  -bc       output batchfile commands\n");
@@ -1779,9 +1779,16 @@ static void usage(void)
     printf("  -C        enable compression\n");
     printf("  -i key    private key file for authentication\n");
     printf("  -batch    disable all interactive prompts\n");
+    printf("  -V        print version information\n");
     cleanup_exit(1);
 }
 
+static void version(void)
+{
+  printf("psftp: %s\n", ver);
+  cleanup_exit(1);
+}
+
 /*
  * Connect to a host.
  */
@@ -1805,11 +1812,27 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
 	    user = userhost;
     }
 
-    /* Try to load settings for this host */
-    do_defaults(host, &cfg);
-    if (cfg.host[0] == '\0') {
-	/* No settings for this host; use defaults */
-	do_defaults(NULL, &cfg);
+    /*
+     * If we haven't loaded session details already (e.g., from -load),
+     * try looking for a session called "host".
+     */
+    if (!loaded_session) {
+	/* Try to load settings for `host' into a temporary config */
+	Config cfg2;
+	cfg2.host[0] = '\0';
+	do_defaults(host, &cfg2);
+	if (cfg2.host[0] != '\0') {
+	    /* Settings present and include hostname */
+	    /* Re-load data into the real config. */
+	    do_defaults(host, &cfg);
+	} else {
+	    /* Session doesn't exist or mention a hostname. */
+	    /* Use `host' as a bare hostname. */
+	    strncpy(cfg.host, host, sizeof(cfg.host) - 1);
+	    cfg.host[sizeof(cfg.host) - 1] = '\0';
+	}
+    } else {
+	/* Patch in hostname `host' to session details. */
 	strncpy(cfg.host, host, sizeof(cfg.host) - 1);
 	cfg.host[sizeof(cfg.host) - 1] = '\0';
     }
@@ -1823,6 +1846,15 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
         cfg.port = 22;
     }
 
+    /*
+     * If saved session / Default Settings says SSH-1 (`1 only' or `1'),
+     * then change it to SSH-2, on the grounds that that's more likely to
+     * work for SFTP. (Can be overridden with `-1' option.)
+     * But if it says `2 only' or `2', respect which.
+     */
+    if (cfg.sshprot != 2 && cfg.sshprot != 3)
+	cfg.sshprot = 2;
+
     /*
      * Enact command-line overrides.
      */
@@ -1890,9 +1922,6 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
     if (portnumber)
 	cfg.port = portnumber;
 
-    /* SFTP uses SSH2 by default always */
-    cfg.sshprot = 2;
-
     /*
      * Disable scary things which shouldn't be enabled for simple
      * things like SCP and SFTP: agent forwarding, port forwarding,
@@ -1932,7 +1961,8 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
 
     back = &ssh_backend;
 
-    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
+    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,
+		     0, cfg.tcp_keepalives);
     if (err != NULL) {
 	fprintf(stderr, "ssh_init: %s\n", err);
 	return 1;
@@ -1988,6 +2018,10 @@ int psftp_main(int argc, char *argv[])
 
     userhost = user = NULL;
 
+    /* Load Default Settings before doing anything else. */
+    do_defaults(NULL, &cfg);
+    loaded_session = FALSE;
+
     errors = 0;
     for (i = 1; i < argc; i++) {
 	int ret;
@@ -2010,6 +2044,8 @@ int psftp_main(int argc, char *argv[])
 	} else if (strcmp(argv[i], "-h") == 0 ||
 		   strcmp(argv[i], "-?") == 0) {
 	    usage();
+	} else if (strcmp(argv[i], "-V") == 0) {
+	    version();
 	} else if (strcmp(argv[i], "-batch") == 0) {
 	    console_batch_mode = 1;
 	} else if (strcmp(argv[i], "-b") == 0 && i + 1 < argc) {
@@ -2030,6 +2066,15 @@ int psftp_main(int argc, char *argv[])
     argv += i;
     back = NULL;
 
+    /*
+     * If the loaded session provides a hostname, and a hostname has not
+     * otherwise been specified, pop it in `userhost' so that
+     * `psftp -load sessname' is sufficient to start a session.
+     */
+    if (!userhost && cfg.host[0] != '\0') {
+	userhost = dupstr(cfg.host);
+    }
+
     /*
      * If a user@host string has already been provided, connect to
      * it now.

+ 2 - 2
putty/PUTTYGEN.C

@@ -1,5 +1,5 @@
 /*
- * PuTTY key generation front end.
+ * PuTTY key generation front end (Windows).
  */
 
 #include <time.h>
@@ -928,7 +928,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
 		       IDC_BITSSTATIC, IDC_BITS, 20);
 	    endbox(&cp);
 	}
-	CheckRadioButton(hwnd, IDC_KEYSSH1, IDC_KEYSSH2DSA, IDC_KEYSSH1);
+	CheckRadioButton(hwnd, IDC_KEYSSH1, IDC_KEYSSH2DSA, IDC_KEYSSH2RSA);
 	CheckMenuRadioItem(state->keymenu, IDC_KEYSSH1, IDC_KEYSSH2DSA,
 			   IDC_KEYSSH1, MF_BYCOMMAND);
 	SetDlgItemInt(hwnd, IDC_BITS, DEFAULT_KEYSIZE, FALSE);

+ 3 - 2
putty/RAW.C

@@ -69,7 +69,8 @@ static void raw_sent(Plug plug, int bufsize)
  */
 static const char *raw_init(void *frontend_handle, void **backend_handle,
 			    Config *cfg,
-			    char *host, int port, char **realhost, int nodelay)
+			    char *host, int port, char **realhost, int nodelay,
+			    int keepalive)
 {
     static const struct plug_function_table fn_table = {
 	raw_closing,
@@ -115,7 +116,7 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
 	logevent(raw->frontend, buf);
 	sfree(buf);
     }
-    raw->s = new_connection(addr, *realhost, port, 0, 1, nodelay,
+    raw->s = new_connection(addr, *realhost, port, 0, 1, nodelay, keepalive,
 			    (Plug) raw, cfg);
     if ((err = sk_socket_error(raw->s)) != NULL)
 	return err;

+ 11 - 1
putty/README

@@ -2,7 +2,8 @@ This is the README for the source archive of PuTTY, a free Win32
 Telnet and SSH client.
 
 If you want to rebuild PuTTY from source, we provide a variety of
-Makefiles and equivalents.
+Makefiles and equivalents. (If you have fetched the source from CVS,
+you'll have to generate the Makefiles yourself -- see below.)
 
 For building on Windows:
 
@@ -46,11 +47,20 @@ For building on Unix:
    on Linux so far; portability problems such as BSD-style ptys or
    different header file requirements are expected.
 
+   There is an `install' target; note that by default it tries to
+   install `man' pages, which need to be built using Halibut first --
+   see below.
+
 All of the Makefiles are generated automatically from the file
 `Recipe' by the Perl script `mkfiles.pl'. Additions and corrections
 to Recipe and the mkfiles.pl are much more useful than additions and
 corrections to the alternative Makefiles themselves.
 
+Documentation (in various formats including Windows Help and Unix
+`man' pages) is to be built from the Halibut (`.but') files in the
+`doc' subdirectory using `doc/Makefile'. Halibut can be found at
+<http://www.chiark.greenend.org.uk/~sgtatham/halibut/>.
+
 The PuTTY home web site is
 
     http://www.chiark.greenend.org.uk/~sgtatham/putty/

+ 84 - 4
putty/RECIPE

@@ -6,6 +6,24 @@
 # really be made by editing this file and/or the Perl script, not
 # by editing the actual Makefiles.
 
+# ------------------------------------------------------------
+# Top-level configuration.
+
+# Overall project name.
+!name putty
+# Locations and types of output Makefiles.
+!makefile vc Makefile.vc
+!makefile vcproj MSVC
+!makefile cygwin Makefile.cyg
+!makefile borland Makefile.bor
+!makefile lcc Makefile.lcc
+!makefile gtk unix/Makefile.gtk
+!makefile mpw mac/Makefile.mpw
+# Source directories.
+!srcdir charset/
+!srcdir unix/
+!srcdir mac/
+
 # Help text added to the top of each Makefile, with /D converted
 # into -D as appropriate for the particular Makefile.
 
@@ -85,18 +103,79 @@
 #
 !end
 
+# ------------------------------------------------------------
+# Additional text added verbatim to each individual Makefile.
+
+# Hack to force version.o to be rebuilt always.
+!begin vc
+version.obj: *.c *.h *.rc
+	cl $(FWHACK) $(VER) $(CFLAGS) /c version.c
+!end
+!begin cygwin
+version.o: FORCE;
+FORCE:
+	$(CC) $(COMPAT) $(FWHACK) $(XFLAGS) $(CFLAGS) $(VER) -c version.c
+!end
+!begin borland
+version.obj: FORCE
+FORCE:
+	bcc32 $(FWHACK) $(VER) $(CFLAGS) /c version.c
+!end
+!begin lcc
+version.o: FORCE
+FORCE:
+	lcc $(FWHACK) $(VER) $(CFLAGS) /c version.c
+!end
+# For Unix, we also need the gross MD5 hack that causes automatic
+# version number selection in release source archives.
+!begin gtk
+version.o: FORCE;
+FORCE:
+	if test -z "$(VER)" && (cd ..; md5sum -c manifest); then \
+		$(CC) $(COMPAT) $(FWHACK) $(XFLAGS) $(CFLAGS) `cat ../version.def` -c ../version.c; \
+	else \
+		$(CC) $(COMPAT) $(FWHACK) $(XFLAGS) $(CFLAGS) $(VER) -c ../version.c; \
+	fi
+!end
+
+# `make install' target for Unix.
+!begin gtk
+install:
+	$(INSTALL_PROGRAM) -m 755 plink $(DESTDIR)$(bindir)/plink
+	$(INSTALL_PROGRAM) -m 755 pscp $(DESTDIR)$(bindir)/pscp
+	$(INSTALL_PROGRAM) -m 755 psftp $(DESTDIR)$(bindir)/psftp
+	$(INSTALL_PROGRAM) -m 755 pterm $(DESTDIR)$(bindir)/pterm
+	$(INSTALL_PROGRAM) -m 755 putty $(DESTDIR)$(bindir)/putty
+	$(INSTALL_PROGRAM) -m 755 puttygen $(DESTDIR)$(bindir)/puttygen
+	$(INSTALL_PROGRAM) -m 755 puttytel $(DESTDIR)$(bindir)/puttytel
+	$(INSTALL_DATA) -m 644 ../doc/plink.1 $(DESTDIR)$(man1dir)/plink.1
+	$(INSTALL_DATA) -m 644 ../doc/pscp.1 $(DESTDIR)$(man1dir)/pscp.1
+	$(INSTALL_DATA) -m 644 ../doc/psftp.1 $(DESTDIR)$(man1dir)/psftp.1
+	$(INSTALL_DATA) -m 644 ../doc/pterm.1 $(DESTDIR)$(man1dir)/pterm.1
+	$(INSTALL_DATA) -m 644 ../doc/putty.1 $(DESTDIR)$(man1dir)/putty.1
+	$(INSTALL_DATA) -m 644 ../doc/puttygen.1 $(DESTDIR)$(man1dir)/puttygen.1
+	$(INSTALL_DATA) -m 644 ../doc/puttytel.1 $(DESTDIR)$(man1dir)/puttytel.1
+
+install-strip:
+	$(MAKE) install INSTALL_PROGRAM="$(INSTALL_PROGRAM) -s"
+!end
+
+# ------------------------------------------------------------
 # Definitions of object groups. A group name, followed by an =,
 # followed by any number of objects or other already-defined group
 # names. A line beginning `+' is assumed to continue the previous
 # line.
 
+# Terminal emulator and its (platform-independent) dependencies.
+TERMINAL = terminal wcwidth ldiscucs logging tree234 minibidi
+         + config dialog
+
 # GUI front end and terminal emulator (putty, puttytel).
-GUITERM  = window windlg winctrls terminal sizetip wcwidth unicode ldiscucs
-         + logging printing winutils dialog config wincfg tree234
+GUITERM  = TERMINAL window windlg winctrls sizetip unicode printing
+         + winutils wincfg
 
 # Same thing on Unix.
-UXTERM   = pterm config uxcfg dialog gtkdlg gtkcols gtkpanel tree234
-         + terminal wcwidth uxucs ldiscucs logging uxprint xkeysym
+UXTERM   = TERMINAL pterm uxcfg gtkdlg gtkcols gtkpanel uxucs uxprint xkeysym
 
 # Non-SSH back ends (putty, puttytel, plink).
 NONSSH   = telnet raw rlogin ldisc
@@ -128,6 +207,7 @@ CHARSET  = sbcsdat slookup sbcs utf8 toucs fromucs xenc mimeenc macenc localenc
 LIBS     = advapi32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib
          + shell32.lib winmm.lib imm32.lib winspool.lib
 
+# ------------------------------------------------------------
 # Definitions of actual programs. The program name, followed by a
 # colon, followed by a list of objects. Also in the list may be the
 # keywords [G] for Windows GUI app, [C] for Console app, [X] for

+ 2 - 2
putty/RLOGIN.C

@@ -100,7 +100,7 @@ static void rlogin_sent(Plug plug, int bufsize)
 static const char *rlogin_init(void *frontend_handle, void **backend_handle,
 			       Config *cfg,
 			       char *host, int port, char **realhost,
-			       int nodelay)
+			       int nodelay, int keepalive)
 {
     static const struct plug_function_table fn_table = {
 	rlogin_closing,
@@ -149,7 +149,7 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
 	sfree(buf);
     }
     rlogin->s = new_connection(addr, *realhost, port, 1, 0,
-			       nodelay, (Plug) rlogin, cfg);
+			       nodelay, keepalive, (Plug) rlogin, cfg);
     if ((err = sk_socket_error(rlogin->s)) != NULL)
 	return err;
 

+ 94 - 18
putty/SCP.C

@@ -36,6 +36,10 @@ static int prev_stats_len = 0;
 static int scp_unsafe_mode = 0;
 static int errs = 0;
 static int gui_mode = 0;
+static int try_scp = 1;
+static int try_sftp = 1;
+static int main_cmd_is_sftp = 0;
+static int fallback_cmd_is_sftp = 0;
 static int using_sftp = 0;
 
 static Backend *back;
@@ -262,7 +266,13 @@ static void ssh_scp_init(void)
 	if (ssh_sftp_loop_iteration() < 0)
 	    return;		       /* doom */
     }
-    using_sftp = !ssh_fallback_cmd(backhandle);
+
+    /* Work out which backend we ended up using. */
+    if (!ssh_fallback_cmd(backhandle))
+	using_sftp = main_cmd_is_sftp;
+    else
+	using_sftp = fallback_cmd_is_sftp;
+
     if (verbose) {
 	if (using_sftp)
 	    tell_user(stderr, "Using SFTP");
@@ -311,11 +321,27 @@ static void do_cmd(char *host, char *user, char *cmd)
     if (host == NULL || host[0] == '\0')
 	bump("Empty host name");
 
-    /* Try to load settings for this host */
-    do_defaults(host, &cfg);
-    if (cfg.host[0] == '\0') {
-	/* No settings for this host; use defaults */
-	do_defaults(NULL, &cfg);
+    /*
+     * If we haven't loaded session details already (e.g., from -load),
+     * try looking for a session called "host".
+     */
+    if (!loaded_session) {
+	/* Try to load settings for `host' into a temporary config */
+	Config cfg2;
+	cfg2.host[0] = '\0';
+	do_defaults(host, &cfg2);
+	if (cfg2.host[0] != '\0') {
+	    /* Settings present and include hostname */
+	    /* Re-load data into the real config. */
+	    do_defaults(host, &cfg);
+	} else {
+	    /* Session doesn't exist or mention a hostname. */
+	    /* Use `host' as a bare hostname. */
+	    strncpy(cfg.host, host, sizeof(cfg.host) - 1);
+	    cfg.host[sizeof(cfg.host) - 1] = '\0';
+	}
+    } else {
+	/* Patch in hostname `host' to session details. */
 	strncpy(cfg.host, host, sizeof(cfg.host) - 1);
 	cfg.host[sizeof(cfg.host) - 1] = '\0';
     }
@@ -402,18 +428,46 @@ static void do_cmd(char *host, char *user, char *cmd)
     cfg.portfwd[0] = cfg.portfwd[1] = '\0';
 
     /*
+     * Set up main and possibly fallback command depending on
+     * options specified by user.
      * Attempt to start the SFTP subsystem as a first choice,
      * falling back to the provided scp command if that fails.
      */
-    strcpy(cfg.remote_cmd, "sftp");
-    cfg.ssh_subsys = TRUE;
-    cfg.remote_cmd_ptr2 = cmd;
-    cfg.ssh_subsys2 = FALSE;
+    cfg.remote_cmd_ptr2 = NULL;
+    if (try_sftp) {
+	/* First choice is SFTP subsystem. */
+	main_cmd_is_sftp = 1;
+	strcpy(cfg.remote_cmd, "sftp");
+	cfg.ssh_subsys = TRUE;
+	if (try_scp) {
+	    /* Fallback is to use the provided scp command. */
+	    fallback_cmd_is_sftp = 0;
+	    cfg.remote_cmd_ptr2 = cmd;
+	    cfg.ssh_subsys2 = FALSE;
+	} else {
+	    /* Since we're not going to try SCP, we may as well try
+	     * harder to find an SFTP server, since in the current
+	     * implementation we have a spare slot. */
+	    fallback_cmd_is_sftp = 1;
+	    /* see psftp.c for full explanation of this kludge */
+	    cfg.remote_cmd_ptr2 = 
+		"test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
+		"test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
+		"exec sftp-server";
+	    cfg.ssh_subsys2 = FALSE;
+	}
+    } else {
+	/* Don't try SFTP at all; just try the scp command. */
+	main_cmd_is_sftp = 0;
+	cfg.remote_cmd_ptr = cmd;
+	cfg.ssh_subsys = FALSE;
+    }
     cfg.nopty = TRUE;
 
     back = &ssh_backend;
 
-    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
+    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost, 
+		     0, cfg.tcp_keepalives);
     if (err != NULL)
 	bump("ssh_init: %s", err);
     logctx = log_init(NULL, &cfg);
@@ -433,7 +487,7 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
 {
     float ratebs;
     unsigned long eta;
-    char etastr[10];
+    char *etastr;
     int pct;
     int len;
     int elap;
@@ -449,8 +503,8 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
 	eta = size - done;
     else
 	eta = (unsigned long) ((size - done) / ratebs);
-    sprintf(etastr, "%02ld:%02ld:%02ld",
-	    eta / 3600, (eta % 3600) / 60, eta % 60);
+    etastr = dupprintf("%02ld:%02ld:%02ld",
+		       eta / 3600, (eta % 3600) / 60, eta % 60);
 
     pct = (int) (100 * (done * 1.0 / size));
 
@@ -469,6 +523,8 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
 
 	fflush(stdout);
     }
+
+    free(etastr);
 }
 
 /*
@@ -1796,11 +1852,12 @@ static void sink(char *targ, char *src)
 	received = 0;
 	while (received < act.size) {
 	    char transbuf[4096];
-	    int blksize, read;
+	    unsigned long blksize;
+	    int read;
 	    blksize = 4096;
-	    if (blksize > (int)(act.size - received))
+	    if (blksize > (act.size - received))
 		blksize = act.size - received;
-	    read = scp_recv_filedata(transbuf, blksize);
+	    read = scp_recv_filedata(transbuf, (int)blksize);
 	    if (read <= 0)
 		bump("Lost connection");
 	    if (wrerror)
@@ -2049,7 +2106,7 @@ static void usage(void)
     printf("Usage: pscp [options] [user@]host:source target\n");
     printf
 	("       pscp [options] source [source...] [user@]host:target\n");
-    printf("       pscp [options] -ls user@host:filespec\n");
+    printf("       pscp [options] -ls [user@]host:filespec\n");
     printf("Options:\n");
     printf("  -p        preserve file attributes\n");
     printf("  -q        quiet, don't show statistics\n");
@@ -2064,6 +2121,9 @@ static void usage(void)
     printf("  -i key    private key file for authentication\n");
     printf("  -batch    disable all interactive prompts\n");
     printf("  -unsafe   allow server-side wildcards (DANGEROUS)\n");
+    printf("  -V        print version information\n");
+    printf("  -sftp     force use of SFTP protocol\n");
+    printf("  -scp      force use of SCP protocol\n");
 #if 0
     /*
      * -gui is an internal option, used by GUI front ends to get
@@ -2078,6 +2138,12 @@ static void usage(void)
     cleanup_exit(1);
 }
 
+void version(void)
+{
+    printf("pscp: %s\n", ver);
+    cleanup_exit(1);
+}
+
 void cmdline_error(char *p, ...)
 {
     va_list ap;
@@ -2108,6 +2174,10 @@ int psftp_main(int argc, char *argv[])
     ssh_get_line = &console_get_line;
     sk_init();
 
+    /* Load Default Settings before doing anything else. */
+    do_defaults(NULL, &cfg);
+    loaded_session = FALSE;
+
     for (i = 1; i < argc; i++) {
 	int ret;
 	if (argv[i][0] != '-')
@@ -2129,6 +2199,8 @@ int psftp_main(int argc, char *argv[])
 	    statistics = 0;
 	} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) {
 	    usage();
+	} else if (strcmp(argv[i], "-V") == 0) {
+            version();
 	} else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
 	    gui_enable(argv[++i]);
 	    gui_mode = 1;
@@ -2139,6 +2211,10 @@ int psftp_main(int argc, char *argv[])
 	    console_batch_mode = 1;
 	} else if (strcmp(argv[i], "-unsafe") == 0) {
 	    scp_unsafe_mode = 1;
+	} else if (strcmp(argv[i], "-sftp") == 0) {
+	    try_scp = 0; try_sftp = 1;
+	} else if (strcmp(argv[i], "-scp") == 0) {
+	    try_scp = 1; try_sftp = 0;
 	} else if (strcmp(argv[i], "--") == 0) {
 	    i++;
 	    break;

+ 10 - 2
putty/SETTINGS.C

@@ -1,5 +1,5 @@
 /*
- * settings.c: read and write saved sessions.
+ * settings.c: read and write saved sessions. (platform-independent)
  */
 
 #include <stdio.h>
@@ -182,6 +182,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
     write_setting_i(sesskey, "PingInterval", cfg->ping_interval / 60);	/* minutes */
     write_setting_i(sesskey, "PingIntervalSecs", cfg->ping_interval % 60);	/* seconds */
     write_setting_i(sesskey, "TCPNoDelay", cfg->tcp_nodelay);
+    write_setting_i(sesskey, "TCPKeepalives", cfg->tcp_keepalives);
     write_setting_s(sesskey, "TerminalType", cfg->termtype);
     write_setting_s(sesskey, "TerminalSpeed", cfg->termspeed);
 
@@ -278,6 +279,8 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
     write_setting_i(sesskey, "DECOriginMode", cfg->dec_om);
     write_setting_i(sesskey, "AutoWrapMode", cfg->wrap_mode);
     write_setting_i(sesskey, "LFImpliesCR", cfg->lfhascr);
+    write_setting_i(sesskey, "DisableArabicShaping", cfg->arabicshaping);
+    write_setting_i(sesskey, "DisableBidi", cfg->bidi);
     write_setting_i(sesskey, "WinNameAlways", cfg->win_name_always);
     write_setting_s(sesskey, "WinTitle", cfg->wintitle);
     write_setting_i(sesskey, "TermWidth", cfg->width);
@@ -287,6 +290,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
     write_setting_i(sesskey, "UseSystemColours", cfg->system_colour);
     write_setting_i(sesskey, "TryPalette", cfg->try_palette);
     write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour);
+
     for (i = 0; i < 22; i++) {
 	char buf[20], buf2[30];
 	sprintf(buf, "Colour%d", i);
@@ -412,6 +416,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
 	cfg->ping_interval = pingmin * 60 + pingsec;
     }
     gppi(sesskey, "TCPNoDelay", 1, &cfg->tcp_nodelay);
+    gppi(sesskey, "TCPKeepalives", 0, &cfg->tcp_keepalives);
     gpps(sesskey, "TerminalType", "xterm", cfg->termtype,
 	 sizeof(cfg->termtype));
     gpps(sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed,
@@ -539,6 +544,8 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
     gppi(sesskey, "DECOriginMode", 0, &cfg->dec_om);
     gppi(sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
     gppi(sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
+    gppi(sesskey, "DisableArabicShaping", 0, &cfg->arabicshaping);
+    gppi(sesskey, "DisableBidi", 0, &cfg->bidi);
     gppi(sesskey, "WinNameAlways", 1, &cfg->win_name_always);
     gpps(sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
     gppi(sesskey, "TermWidth", 80, &cfg->width);
@@ -548,6 +555,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
     gppi(sesskey, "UseSystemColours", 0, &cfg->system_colour);
     gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
     gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);
+
     for (i = 0; i < 22; i++) {
 	static const char *const defaults[] = {
 	    "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
@@ -613,7 +621,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
     gppi(sesskey, "BCE", 1, &cfg->bce);
     gppi(sesskey, "BlinkText", 0, &cfg->blinktext);
     gppi(sesskey, "X11Forward", 0, &cfg->x11_forward);
-    gpps(sesskey, "X11Display", "localhost:0", cfg->x11_display,
+    gpps(sesskey, "X11Display", "", cfg->x11_display,
 	 sizeof(cfg->x11_display));
     gppi(sesskey, "X11AuthType", X11_MIT, &cfg->x11_auth);
 

File diff suppressed because it is too large
+ 291 - 131
putty/SSH.C


+ 11 - 6
putty/SSH.H

@@ -55,10 +55,10 @@ struct dss_key {
     Bignum p, q, g, y, x;
 };
 
-int makekey(unsigned char *data, struct RSAKey *result,
+int makekey(unsigned char *data, int len, struct RSAKey *result,
 	    unsigned char **keystr, int order);
-int makeprivate(unsigned char *data, struct RSAKey *result);
-void rsaencrypt(unsigned char *data, int length, struct RSAKey *key);
+int makeprivate(unsigned char *data, int len, struct RSAKey *result);
+int rsaencrypt(unsigned char *data, int length, struct RSAKey *key);
 Bignum rsadecrypt(Bignum input, struct RSAKey *key);
 void rsasign(unsigned char *data, int length, struct RSAKey *key);
 void rsasanitise(struct RSAKey *key);
@@ -67,7 +67,7 @@ void rsastr_fmt(char *str, struct RSAKey *key);
 void rsa_fingerprint(char *str, int len, struct RSAKey *key);
 int rsa_verify(struct RSAKey *key);
 unsigned char *rsa_public_blob(struct RSAKey *key, int *len);
-int rsa_public_blob_len(void *data);
+int rsa_public_blob_len(void *data, int maxlen);
 void freersakey(struct RSAKey *key);
 
 typedef unsigned int word32;
@@ -281,10 +281,15 @@ extern void x11_unthrottle(Socket s);
 extern void x11_override_throttle(Socket s, int enable);
 extern int x11_get_screen_number(char *display);
 void x11_get_real_auth(void *authv, char *display);
+char *x11_display(const char *display);
 
-/* Platfdorm-dependent X11 function */
+/* Platform-dependent X11 functions */
 extern void platform_get_x11_auth(char *display, int *proto,
                                   unsigned char *data, int *datalen);
+extern const char platform_x11_best_transport[];
+/* best X11 hostname for this platform if none specified */
+SockAddr platform_get_x11_unix_address(int displaynum, char **canonicalname);
+/* make up a SockAddr naming the address for displaynum */
 
 Bignum copybn(Bignum b);
 Bignum bn_power_2(int n);
@@ -296,7 +301,7 @@ Bignum modmul(Bignum a, Bignum b, Bignum mod);
 void decbn(Bignum n);
 extern Bignum Zero, One;
 Bignum bignum_from_bytes(const unsigned char *data, int nbytes);
-int ssh1_read_bignum(const unsigned char *data, Bignum * result);
+int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result);
 int bignum_bitcount(Bignum bn);
 int ssh1_bignum_length(Bignum bn);
 int ssh2_bignum_length(Bignum bn);

+ 25 - 7
putty/SSHBN.C

@@ -3,6 +3,7 @@
  */
 
 #include <stdio.h>
+#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -226,16 +227,25 @@ static void internal_mod(BignumInt *a, int alen,
 
 /*
  * Compute (base ^ exp) % mod.
- * The base MUST be smaller than the modulus.
- * The most significant word of mod MUST be non-zero.
- * We assume that the result array is the same size as the mod array.
  */
-Bignum modpow(Bignum base, Bignum exp, Bignum mod)
+Bignum modpow(Bignum base_in, Bignum exp, Bignum mod)
 {
     BignumInt *a, *b, *n, *m;
     int mshift;
     int mlen, i, j;
-    Bignum result;
+    Bignum base, result;
+
+    /*
+     * The most significant word of mod needs to be non-zero. It
+     * should already be, but let's make sure.
+     */
+    assert(mod[mod[0]] != 0);
+
+    /*
+     * Make sure the base is smaller than the modulus, by reducing
+     * it modulo the modulus if not.
+     */
+    base = bigmod(base_in, mod);
 
     /* Allocate m of size mlen, copy mod to m */
     /* We use big endian internally */
@@ -331,6 +341,8 @@ Bignum modpow(Bignum base, Bignum exp, Bignum mod)
 	n[i] = 0;
     sfree(n);
 
+    freebn(base);
+
     return result;
 }
 
@@ -528,19 +540,25 @@ Bignum bignum_from_bytes(const unsigned char *data, int nbytes)
 
 /*
  * Read an ssh1-format bignum from a data buffer. Return the number
- * of bytes consumed.
+ * of bytes consumed, or -1 if there wasn't enough data.
  */
-int ssh1_read_bignum(const unsigned char *data, Bignum * result)
+int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result)
 {
     const unsigned char *p = data;
     int i;
     int w, b;
 
+    if (len < 2)
+	return -1;
+
     w = 0;
     for (i = 0; i < 2; i++)
 	w = (w << 8) + *p++;
     b = (w + 7) / 8;		       /* bits -> bytes */
 
+    if (len < b+2)
+	return -1;
+
     if (!result)		       /* just return length */
 	return b + 2;
 

+ 1 - 1
putty/SSHDH.C

@@ -123,7 +123,7 @@ Bignum dh_create_e(void *handle, int nbits)
 	    ssh1_write_bignum(buf, ctx->qmask);
 	    for (i = 2; i < nbytes; i++)
 		buf[i] &= random_byte();
-	    ssh1_read_bignum(buf, &ctx->x);
+	    ssh1_read_bignum(buf, nbytes, &ctx->x);   /* can't fail */
 	} else {
 	    int b, nb;
 	    ctx->x = bn_power_2(nbits);

+ 14 - 14
putty/SSHPUBK.C

@@ -79,8 +79,8 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
     i += 4;
 
     /* Now the serious stuff. An ordinary SSH 1 public key. */
-    i += makekey(buf + i, key, NULL, 1);
-    if (len - i < 0)
+    i += makekey(buf + i, len, key, NULL, 1);
+    if (i < 0)
 	goto end;		       /* overran */
 
     if (pub_only) {
@@ -138,18 +138,18 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
      * decryption exponent, and then the three auxiliary values
      * (iqmp, q, p).
      */
-    i += makeprivate(buf + i, key);
-    if (len - i < 0)
-	goto end;
-    i += ssh1_read_bignum(buf + i, &key->iqmp);
-    if (len - i < 0)
-	goto end;
-    i += ssh1_read_bignum(buf + i, &key->q);
-    if (len - i < 0)
-	goto end;
-    i += ssh1_read_bignum(buf + i, &key->p);
-    if (len - i < 0)
-	goto end;
+    j = makeprivate(buf + i, len - i, key);
+    if (j < 0) goto end;
+    i += j;
+    j = ssh1_read_bignum(buf + i, len - i, &key->iqmp);
+    if (j < 0) goto end;
+    i += j;
+    j = ssh1_read_bignum(buf + i, len - i, &key->q);
+    if (j < 0) goto end;
+    i += j;
+    j = ssh1_read_bignum(buf + i, len - i, &key->p);
+    if (j < 0) goto end;
+    i += j;
 
     if (!rsa_verify(key)) {
 	*error = "rsa_verify failed";

+ 49 - 15
putty/SSHRSA.C

@@ -22,11 +22,14 @@
     (cp)[2] = (unsigned char)((value) >> 8); \
     (cp)[3] = (unsigned char)(value); }
 
-int makekey(unsigned char *data, struct RSAKey *result,
+int makekey(unsigned char *data, int len, struct RSAKey *result,
 	    unsigned char **keystr, int order)
 {
     unsigned char *p = data;
-    int i;
+    int i, n;
+
+    if (len < 4)
+	return -1;
 
     if (result) {
 	result->bits = 0;
@@ -35,36 +38,53 @@ int makekey(unsigned char *data, struct RSAKey *result,
     } else
 	p += 4;
 
+    len -= 4;
+
     /*
      * order=0 means exponent then modulus (the keys sent by the
      * server). order=1 means modulus then exponent (the keys
      * stored in a keyfile).
      */
 
-    if (order == 0)
-	p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
+    if (order == 0) {
+	n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
+	if (n < 0) return -1;
+	p += n;
+	len -= n;
+    }
+
+    n = ssh1_read_bignum(p, len, result ? &result->modulus : NULL);
+    if (n < 0) return -1;
     if (result)
-	result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
+	result->bytes = n - 2;
     if (keystr)
 	*keystr = p + 2;
-    p += ssh1_read_bignum(p, result ? &result->modulus : NULL);
-    if (order == 1)
-	p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
-
+    p += n;
+    len -= n;
+
+    if (order == 1) {
+	n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
+	if (n < 0) return -1;
+	p += n;
+	len -= n;
+    }
     return p - data;
 }
 
-int makeprivate(unsigned char *data, struct RSAKey *result)
+int makeprivate(unsigned char *data, int len, struct RSAKey *result)
 {
-    return ssh1_read_bignum(data, &result->private_exponent);
+    return ssh1_read_bignum(data, len, &result->private_exponent);
 }
 
-void rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
+int rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
 {
     Bignum b1, b2;
     int i;
     unsigned char *p;
 
+    if (key->bytes < length + 4)
+	return 0;		       /* RSA key too short! */
+
     memmove(data + key->bytes - length, data, length);
     data[0] = 0;
     data[1] = 2;
@@ -87,6 +107,8 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
 
     freebn(b1);
     freebn(b2);
+
+    return 1;
 }
 
 static void sha512_mpint(SHA512_State * s, Bignum b)
@@ -378,13 +400,25 @@ unsigned char *rsa_public_blob(struct RSAKey *key, int *len)
 }
 
 /* Given a public blob, determine its length. */
-int rsa_public_blob_len(void *data)
+int rsa_public_blob_len(void *data, int maxlen)
 {
     unsigned char *p = (unsigned char *)data;
+    int n;
 
+    if (maxlen < 4)
+	return -1;
     p += 4;			       /* length word */
-    p += ssh1_read_bignum(p, NULL);    /* exponent */
-    p += ssh1_read_bignum(p, NULL);    /* modulus */
+    maxlen -= 4;
+
+    n = ssh1_read_bignum(p, maxlen, NULL);    /* exponent */
+    if (n < 0)
+	return -1;
+    p += n;
+
+    n = ssh1_read_bignum(p, maxlen, NULL);    /* modulus */
+    if (n < 0)
+	return -1;
+    p += n;
 
     return p - (unsigned char *)data;
 }

+ 2 - 2
putty/TELNET.C

@@ -674,7 +674,7 @@ static void telnet_sent(Plug plug, int bufsize)
 static const char *telnet_init(void *frontend_handle, void **backend_handle,
 			       Config *cfg,
 			       char *host, int port, char **realhost,
-			       int nodelay)
+			       int nodelay, int keepalive)
 {
     static const struct plug_function_table fn_table = {
 	telnet_closing,
@@ -729,7 +729,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
 	sfree(buf);
     }
     telnet->s = new_connection(addr, *realhost, port, 0, 1,
-			       nodelay, (Plug) telnet, &telnet->cfg);
+			       nodelay, keepalive, (Plug) telnet, &telnet->cfg);
     if ((err = sk_socket_error(telnet->s)) != NULL)
 	return err;
 

+ 152 - 6
putty/TERMINAL.C

@@ -237,6 +237,15 @@ void term_update(Terminal *term)
 	    term->seen_disp_event = 0;
 	    need_sbar_update = TRUE;
 	}
+
+	/* Allocate temporary buffers for Arabic shaping and bidi. */
+	if (!term->cfg.arabicshaping || !term->cfg.bidi)
+	{
+	    term->wcFrom = sresize(term->wcFrom, term->cols, bidi_char);
+	    term->ltemp = sresize(term->ltemp, term->cols+1, unsigned long);
+	    term->wcTo = sresize(term->wcTo, term->cols, bidi_char);
+	}
+
 	if (need_sbar_update)
 	    update_sbar(term);
 	do_paint(term, ctx, TRUE);
@@ -428,6 +437,12 @@ Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata,
     term->resize_fn = NULL;
     term->resize_ctx = NULL;
     term->in_term_out = FALSE;
+    term->ltemp = NULL;
+    term->wcFrom = NULL;
+    term->wcTo = NULL;
+
+    term->bidi_cache_size = 0;
+    term->pre_bidi_cache = term->post_bidi_cache = NULL;
 
     return term;
 }
@@ -436,6 +451,7 @@ void term_free(Terminal *term)
 {
     unsigned long *line;
     struct beeptime *beep;
+    int i;
 
     while ((line = delpos234(term->scrollback, 0)) != NULL)
 	sfree(line);
@@ -457,6 +473,17 @@ void term_free(Terminal *term)
 	printer_finish_job(term->print_job);
     bufchain_clear(&term->printer_buf);
     sfree(term->paste_buffer);
+    sfree(term->ltemp);
+    sfree(term->wcFrom);
+    sfree(term->wcTo);
+
+    for (i = 0; i < term->bidi_cache_size; i++) {
+	sfree(term->pre_bidi_cache[i]);
+	sfree(term->post_bidi_cache[i]);
+    }
+    sfree(term->pre_bidi_cache);
+    sfree(term->post_bidi_cache);
+
     sfree(term);
 }
 
@@ -3302,13 +3329,66 @@ static int linecmp(Terminal *term, unsigned long *a, unsigned long *b)
 }
 #endif
 
+/*
+ * To prevent having to run the reasonably tricky bidi algorithm
+ * too many times, we maintain a cache of the last lineful of data
+ * fed to the algorithm on each line of the display.
+ */
+static int term_bidi_cache_hit(Terminal *term, int line,
+			       unsigned long *lbefore, int width)
+{
+    if (!term->pre_bidi_cache)
+	return FALSE;		       /* cache doesn't even exist yet! */
+
+    if (line >= term->bidi_cache_size)
+	return FALSE;		       /* cache doesn't have this many lines */
+
+    if (!term->pre_bidi_cache[line])
+	return FALSE;		       /* cache doesn't contain _this_ line */
+
+    if (!memcmp(term->pre_bidi_cache[line], lbefore,
+		width * sizeof(unsigned long)))
+	return TRUE;		       /* aha! the line matches the cache */
+
+    return FALSE;		       /* it didn't match. */
+}
+
+static void term_bidi_cache_store(Terminal *term, int line,
+				  unsigned long *lbefore,
+				  unsigned long *lafter, int width)
+{
+    if (!term->pre_bidi_cache || term->bidi_cache_size <= line) {
+	int j = term->bidi_cache_size;
+	term->bidi_cache_size = line+1;
+	term->pre_bidi_cache = sresize(term->pre_bidi_cache,
+				       term->bidi_cache_size,
+				       unsigned long *);
+	term->post_bidi_cache = sresize(term->post_bidi_cache,
+					term->bidi_cache_size,
+					unsigned long *);
+	while (j < term->bidi_cache_size) {
+	    term->pre_bidi_cache[j] = term->post_bidi_cache[j] = NULL;
+	    j++;
+	}
+    }
+
+    sfree(term->pre_bidi_cache[line]);
+    sfree(term->post_bidi_cache[line]);
+
+    term->pre_bidi_cache[line] = snewn(width, unsigned long);
+    term->post_bidi_cache[line] = snewn(width, unsigned long);
+
+    memcpy(term->pre_bidi_cache[line], lbefore, width * sizeof(unsigned long));
+    memcpy(term->post_bidi_cache[line], lafter, width * sizeof(unsigned long));
+}
+
 /*
  * Given a context, update the window. Out of paranoia, we don't
  * allow WM_PAINT responses to do scrolling optimisations.
  */
 static void do_paint(Terminal *term, Context ctx, int may_optimise)
 {
-    int i, j, our_curs_y, our_curs_x;
+    int i, it, j, our_curs_y, our_curs_x;
     unsigned long rv, cursor;
     pos scrpos;
     char ch[1024];
@@ -3324,8 +3404,8 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
     if (term->in_vbell) {
 	ticks = GETTICKCOUNT();
 	if (ticks - term->vbell_startpoint >= VBELL_TIMEOUT)
-	    term->in_vbell = FALSE; 
-   }
+	    term->in_vbell = FALSE;
+    }
 
     rv = (!term->rvideo ^ !term->in_vbell ? ATTR_REVERSE : 0);
 
@@ -3411,6 +3491,67 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
 				  term->disptext[idx + term->cols]);
 	term->disptext[idx + term->cols] = ldata[term->cols];
 
+	/* Do Arabic shaping and bidi. */
+	if(!term->cfg.bidi || !term->cfg.arabicshaping) {
+
+	    if (!term_bidi_cache_hit(term, i, ldata, term->cols)) {
+
+		for(it=0; it<term->cols ; it++)
+		{
+		    int uc = (ldata[it] & 0xFFFF);
+
+		    switch (uc & CSET_MASK) {
+		      case ATTR_LINEDRW:
+			if (!term->cfg.rawcnp) {
+			    uc = term->ucsdata->unitab_xterm[uc & 0xFF];
+			    break;
+			}
+		      case ATTR_ASCII:
+			uc = term->ucsdata->unitab_line[uc & 0xFF];
+			break;
+		      case ATTR_SCOACS:
+			uc = term->ucsdata->unitab_scoacs[uc&0xFF];
+			break;
+		    }
+		    switch (uc & CSET_MASK) {
+		      case ATTR_ACP:
+			uc = term->ucsdata->unitab_font[uc & 0xFF];
+			break;
+		      case ATTR_OEMCP:
+			uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
+			break;
+		    }
+
+		    term->wcFrom[it].origwc = term->wcFrom[it].wc = uc;
+		    term->wcFrom[it].index = it;
+		}
+
+		if(!term->cfg.bidi)
+		    do_bidi(term->wcFrom, term->cols);
+
+		/* this is saved iff done from inside the shaping */
+		if(!term->cfg.bidi && term->cfg.arabicshaping)
+		    for(it=0; it<term->cols; it++)
+			term->wcTo[it] = term->wcFrom[it];
+
+		if(!term->cfg.arabicshaping)
+		    do_shape(term->wcFrom, term->wcTo, term->cols);
+
+		for(it=0; it<term->cols ; it++)
+		{
+		    term->ltemp[it] = ldata[term->wcTo[it].index];
+
+		    if (term->wcTo[it].origwc != term->wcTo[it].wc)
+			term->ltemp[it] = ((term->ltemp[it] & 0xFFFF0000) |
+					   term->wcTo[it].wc);
+		}
+		term_bidi_cache_store(term, i, ldata, term->ltemp, term->cols);
+		ldata = term->ltemp;
+	    } else {
+		ldata = term->post_bidi_cache[i];
+	    }
+	}
+
 	for (j = 0; j < term->cols; j++, idx++) {
 	    unsigned long tattr, tchar;
 	    unsigned long *d = ldata + j;
@@ -3432,8 +3573,9 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
 	    }
 	    tattr |= (tchar & CSET_MASK);
 	    tchar &= CHAR_MASK;
-	    if ((d[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
-		    tattr |= ATTR_WIDE;
+	    if (j < term->cols-1 &&
+		(d[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+		tattr |= ATTR_WIDE;
 
 	    /* Video reversing things */
 	    if (term->selstate == DRAGGING || term->selstate == SELECTED) {
@@ -3799,9 +3941,13 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
 void term_copyall(Terminal *term)
 {
     pos top;
+    pos bottom;
+    tree234 *screen = term->screen;
     top.y = -sblines(term);
     top.x = 0;
-    clipme(term, top, term->curs, 0, TRUE);
+    bottom.y = find_last_nonempty_line(term, screen);
+    bottom.x = term->cols;
+    clipme(term, top, bottom, 0, TRUE);
 }
 
 /*

+ 8 - 0
putty/TERMINAL.H

@@ -208,6 +208,14 @@ struct terminal_tag {
      * through.
      */
     int in_term_out;
+
+    /*
+     * These are buffers used by the bidi and Arabic shaping code.
+     */
+    unsigned long *ltemp;
+    bidi_char *wcFrom, *wcTo;
+    unsigned long **pre_bidi_cache, **post_bidi_cache;
+    int bidi_cache_size;
 };
 
 #define in_utf(term) ((term)->utf || (term)->ucsdata->line_codepage==CP_UTF8)

+ 5 - 5
putty/TESTBACK.C

@@ -1,4 +1,4 @@
-/* $Id: TESTBACK.C,v 1.3 2003/12/30 23:22:26 martinprikryl Exp $ */
+/* $Id: testback.c,v 1.10 2004/06/20 17:07:32 jacob Exp $ */
 /*
  * Copyright (c) 1999 Simon Tatham
  * Copyright (c) 1999 Ben Harris
@@ -34,9 +34,9 @@
 #include "putty.h"
 
 static const char *null_init(void *, void **, Config *, char *, int, char **,
-			     int);
+			     int, int);
 static const char *loop_init(void *, void **, Config *, char *, int, char **,
-			     int);
+			     int, int);
 static void null_free(void *);
 static void loop_free(void *);
 static void null_reconfig(void *, Config *);
@@ -72,14 +72,14 @@ struct loop_state {
 
 static const char *null_init(void *frontend_handle, void **backend_handle,
 			     Config *cfg, char *host, int port,
-			     char **realhost, int nodelay) {
+			     char **realhost, int nodelay, int keepalive) {
 
     return NULL;
 }
 
 static const char *loop_init(void *frontend_handle, void **backend_handle,
 			     Config *cfg, char *host, int port,
-			     char **realhost, int nodelay) {
+			     char **realhost, int nodelay, int keepalive) {
     struct loop_state *st = snew(struct loop_state);
 
     st->term = frontend_handle;

+ 11 - 0
putty/WILDCARD.C

@@ -29,6 +29,17 @@
  *  - All other characters are non-special and match themselves.
  */
 
+/*
+ * Some notes on differences from POSIX globs (IEEE Std 1003.1, 2003 ed.):
+ *  - backslashes act as escapes even within [] bracket expressions
+ *  - does not support [!...] for non-matching list (POSIX are weird);
+ *    NB POSIX allows [^...] as well via "A bracket expression starting
+ *    with an unquoted circumflex character produces unspecified
+ *    results". If we wanted to allow [!...] we might want to define
+ *    [^!] as having its literal meaning (match '^' or '!').
+ *  - none of the scary [[:class:]] stuff, etc
+ */
+
 /*
  * The wildcard matching technique we use is very simple and
  * potentially O(N^2) in running time, but I don't anticipate it

+ 85 - 5
putty/WINDOW.C

@@ -611,7 +611,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 	char *realhost;
 
 	error = back->init(NULL, &backhandle, &cfg,
-			   cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
+			   cfg.host, cfg.port, &realhost, cfg.tcp_nodelay,
+			   cfg.tcp_keepalives);
 	back->provide_logctx(backhandle, logctx);
 	if (error) {
 	    char *str = dupprintf("%s Error", appname);
@@ -1080,6 +1081,36 @@ static void init_palette(void)
 			     defpal[i].rgbtGreen, defpal[i].rgbtBlue);
 }
 
+/*
+ * This is a wrapper to ExtTextOut() to force Windows to display
+ * the precise glyphs we give it. Otherwise it would do its own
+ * bidi and Arabic shaping, and we would end up uncertain which
+ * characters it had put where.
+ */
+static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
+			  unsigned short *lpString, UINT cbCount,
+			  CONST INT *lpDx)
+{
+
+    GCP_RESULTSW gcpr;
+    char *buffer = snewn(cbCount*2+2, char);
+    char *classbuffer = snewn(cbCount, char);
+    memset(&gcpr, 0, sizeof(gcpr));
+    memset(buffer, 0, cbCount*2+2);
+    memset(classbuffer, GCPCLASS_NEUTRAL, cbCount);
+
+    gcpr.lStructSize = sizeof(gcpr);
+    gcpr.lpGlyphs = (void *)buffer;
+    gcpr.lpClass = classbuffer;
+    gcpr.nGlyphs = cbCount;
+
+    GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
+			   FLI_MASK | GCP_CLASSIN);
+
+    ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
+	       buffer, cbCount, lpDx);
+}
+
 /*
  * Initialise all the fonts we will need initially. There may be as many as
  * three or as few as one.  The other (poentially) twentyone fonts are done
@@ -1690,6 +1721,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
     static int ignore_clip = FALSE;
     static int need_backend_resize = FALSE;
     static int fullscr_on_max = FALSE;
+    static UINT last_mousemove = 0;
 
     switch (message) {
       case WM_TIMER:
@@ -2129,7 +2161,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
 	}
 	return 0;
       case WM_MOUSEMOVE:
-	show_mouseptr(1);
+	{
+	    /*
+	     * Windows seems to like to occasionally send MOUSEMOVE
+	     * events even if the mouse hasn't moved. Don't unhide
+	     * the mouse pointer in this case.
+	     */
+	    static WPARAM wp = 0;
+	    static LPARAM lp = 0;
+	    if (wParam != wp || lParam != lp ||
+		last_mousemove != WM_MOUSEMOVE) {
+		show_mouseptr(1);
+		wp = wParam; lp = lParam;
+		last_mousemove = WM_MOUSEMOVE;
+	    }
+	}
 	/*
 	 * Add the mouse position and message time to the random
 	 * number noise.
@@ -2152,7 +2198,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
 	}
 	return 0;
       case WM_NCMOUSEMOVE:
-	show_mouseptr(1);
+	{
+	    static WPARAM wp = 0;
+	    static LPARAM lp = 0;
+	    if (wParam != wp || lParam != lp ||
+		last_mousemove != WM_NCMOUSEMOVE) {
+		show_mouseptr(1);
+		wp = wParam; lp = lParam;
+		last_mousemove = WM_NCMOUSEMOVE;
+	    }
+	}
 	noise_ultralight(lParam);
 	break;
       case WM_IGNORE_CLIP:
@@ -2989,9 +3044,13 @@ void do_text(Context ctx, int x, int y, char *text, int len,
 	for (i = 0; i < len; i++)
 	    wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
 
-	ExtTextOutW(hdc, x,
+	/* print Glyphs as they are, without Windows' Shaping*/
+	exact_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
+		      &line_box, wbuf, len, IpDx);
+/*	ExtTextOutW(hdc, x,
 		    y - font_height * (lattr == LATTR_BOT) + text_adjust,
 		    ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
+ */
 
 	/* And the shadow bold hack. */
 	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
@@ -3170,6 +3229,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 
     HKL kbd_layout = GetKeyboardLayout(0);
 
+    /* keys is for ToAsciiEx. There's some ick here, see below. */
     static WORD keys[3];
     static int compose_char = 0;
     static WPARAM compose_key = 0;
@@ -3861,7 +3921,27 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
 	    keystate[VK_CAPITAL] = 0;
 	}
 
-	r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout);
+	/* XXX how do we know what the max size of the keys array should
+	 * be is? There's indication on MS' website of an Inquire/InquireEx
+	 * functioning returning a KBINFO structure which tells us. */
+	if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+	    /* XXX 'keys' parameter is declared in MSDN documentation as
+	     * 'LPWORD lpChar'.
+	     * The experience of a French user indicates that on
+	     * Win98, WORD[] should be passed in, but on Win2K, it should
+	     * be BYTE[]. German WinXP and my Win2K with "US International"
+	     * driver corroborate this.
+	     * Experimentally I've conditionalised the behaviour on the
+	     * Win9x/NT split, but I suspect it's worse than that.
+	     * See wishlist item `win-dead-keys' for more horrible detail
+	     * and speculations. */
+	    BYTE keybs[3];
+	    int i;
+	    r = ToAsciiEx(wParam, scan, keystate, (LPWORD)keybs, 0, kbd_layout);
+	    for (i=0; i<3; i++) keys[i] = keybs[i];
+	} else {
+	    r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout);
+	}
 #ifdef SHOW_TOASCII_RESULT
 	if (r == 1 && !key_down) {
 	    if (alt_sum) {

+ 4 - 2
putty/WINHELP.H

@@ -29,6 +29,8 @@
 #define WINHELP_CTX_features_qtitle "features.qtitle"
 #define WINHELP_CTX_features_dbackspace "features.dbackspace"
 #define WINHELP_CTX_features_charset "features.charset"
+#define WINHELP_CTX_features_arabicshaping "features.arabicshaping"
+#define WINHELP_CTX_features_bidi "features.bidi"
 #define WINHELP_CTX_terminal_autowrap "terminal.autowrap"
 #define WINHELP_CTX_terminal_decom "terminal.decom"
 #define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr"
@@ -57,9 +59,11 @@
 #define WINHELP_CTX_appearance_hidemouse "appearance.hidemouse"
 #define WINHELP_CTX_appearance_border "appearance.border"
 #define WINHELP_CTX_connection_termtype "connection.termtype"
+#define WINHELP_CTX_connection_termspeed "connection.termspeed"
 #define WINHELP_CTX_connection_username "connection.username"
 #define WINHELP_CTX_connection_keepalive "connection.keepalive"
 #define WINHELP_CTX_connection_nodelay "connection.nodelay"
+#define WINHELP_CTX_connection_tcpkeepalive "connection.tcpkeepalive"
 #define WINHELP_CTX_proxy_type "proxy.type"
 #define WINHELP_CTX_proxy_main "proxy.main"
 #define WINHELP_CTX_proxy_exclude "proxy.exclude"
@@ -67,13 +71,11 @@
 #define WINHELP_CTX_proxy_auth "proxy.auth"
 #define WINHELP_CTX_proxy_command "proxy.command"
 #define WINHELP_CTX_proxy_socksver "proxy.socksver"
-#define WINHELP_CTX_telnet_termspeed "telnet.termspeed"
 #define WINHELP_CTX_telnet_environ "telnet.environ"
 #define WINHELP_CTX_telnet_oldenviron "telnet.oldenviron"
 #define WINHELP_CTX_telnet_passive "telnet.passive"
 #define WINHELP_CTX_telnet_specialkeys "telnet.specialkeys"
 #define WINHELP_CTX_telnet_newline "telnet.newline"
-#define WINHELP_CTX_rlogin_termspeed "rlogin.termspeed"
 #define WINHELP_CTX_rlogin_localuser "rlogin.localuser"
 #define WINHELP_CTX_ssh_nopty "ssh.nopty"
 #define WINHELP_CTX_ssh_ciphers "ssh.ciphers"

+ 3 - 2
putty/WINMISC.C

@@ -1,5 +1,5 @@
 /*
- * winmisc.c: miscellaneous Windows-specific things.
+ * winmisc.c: miscellaneous Windows-specific things
  */
 
 #include <stdio.h>
@@ -14,6 +14,8 @@ void platform_get_x11_auth(char *display, int *proto,
     /* We don't support this at all under Windows. */
 }
 
+const char platform_x11_best_transport[] = "localhost";
+
 Filename filename_from_str(const char *str)
 {
     Filename ret;
@@ -357,4 +359,3 @@ void *minefield_c_realloc(void *p, size_t size)
 }
 
 #endif				/* MINEFIELD */
-

+ 38 - 1
putty/WINNET.C

@@ -599,7 +599,11 @@ static void *sk_tcp_get_private_ptr(Socket s);
 static void sk_tcp_set_frozen(Socket s, int is_frozen);
 static const char *sk_tcp_socket_error(Socket s);
 
+#ifdef MPEXT
 extern char *do_select(Plug plug, SOCKET skt, int startup);
+#else
+extern char *do_select(SOCKET skt, int startup);
+#endif
 
 Socket sk_register(void *sock, Plug plug)
 {
@@ -646,7 +650,11 @@ Socket sk_register(void *sock, Plug plug)
 
     /* Set up a select mechanism. This could be an AsyncSelect on a
      * window, or an EventSelect on an event object. */
+#ifdef MPEXT
     errstr = do_select(plug, ret->s, 1);
+#else
+    errstr = do_select(ret->s, 1);
+#endif
     if (errstr) {
 	ret->error = errstr;
 	return (Socket) ret;
@@ -658,7 +666,7 @@ Socket sk_register(void *sock, Plug plug)
 }
 
 Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
-	      int nodelay, Plug plug)
+	      int nodelay, int keepalive, Plug plug)
 {
     static const struct socket_function_table fn_table = {
 	sk_tcp_plug,
@@ -722,6 +730,11 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
 	p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
     }
 
+    if (keepalive) {
+	BOOL b = TRUE;
+	p_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
+    }
+
     /*
      * Bind to local address.
      */
@@ -797,7 +810,11 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
 
     /* Set up a select mechanism. This could be an AsyncSelect on a
      * window, or an EventSelect on an event object. */
+#ifdef MPEXT
     errstr = do_select(plug, s, 1);
+#else
+    errstr = do_select(s, 1);
+#endif
     if (errstr) {
 	ret->error = errstr;
 	return (Socket) ret;
@@ -966,7 +983,11 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
 
     /* Set up a select mechanism. This could be an AsyncSelect on a
      * window, or an EventSelect on an event object. */
+#ifdef MPEXT
     errstr = do_select(plug, s, 1);
+#else
+    errstr = do_select(s, 1);
+#endif
     if (errstr) {
 	ret->error = errstr;
 	return (Socket) ret;
@@ -979,11 +1000,19 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
 
 static void sk_tcp_close(Socket sock)
 {
+#ifdef MPEXT
     extern char *do_select(Plug plug, SOCKET skt, int startup);
+#else
+	extern char *do_select(SOCKET skt, int startup);
+#endif
     Actual_Socket s = (Actual_Socket) sock;
 
     del234(sktree, s);
+#ifdef MPEXT
     do_select(s->plug, s->s, 0);
+#else
+    do_select(s->s, 0);
+#endif
     p_closesocket(s->s);
     sfree(s);
 }
@@ -1357,3 +1386,11 @@ int net_service_lookup(char *service)
     else
 	return 0;
 }
+
+SockAddr platform_get_x11_unix_address(int displaynum, char **canonicalname)
+{
+    SockAddr ret = snew(struct SockAddr_tag);
+    memset(ret, 0, sizeof(struct SockAddr_tag));
+    ret->error = "unix sockets not supported on this platform";
+    return ret;
+}

+ 1 - 1
putty/WINUTILS.C

@@ -1,5 +1,5 @@
 /*
- * winutils.c: miscellaneous Windows utilities
+ * winutils.c: miscellaneous Windows utilities for GUI apps
  */
 
 #include <stdio.h>

+ 33 - 18
putty/X11FWD.C

@@ -226,6 +226,18 @@ int x11_get_screen_number(char *display)
     return atoi(display + n + 1);
 }
 
+/* Find the right display, returns an allocated string */
+char *x11_display(const char *display) {
+    if(!display || !*display)
+	if(!(display = getenv("DISPLAY")))
+	    display = ":0";
+    if(display[0] == ':') {
+	/* no transport specified, use whatever we think is best */
+	return dupcat(platform_x11_best_transport, display, (char *)0);
+    } else
+	return dupstr(display);
+}
+
 /*
  * Called to set up the raw connection.
  * 
@@ -250,36 +262,39 @@ const char *x11_init(Socket * s, char *display, void *c, void *auth,
     int n, displaynum;
     struct X11Private *pr;
 
+    /* default display */
+    display = x11_display(display);
     /*
      * Split up display name into host and display-number parts.
      */
     n = strcspn(display, ":");
+    assert(n != 0);		/* x11_display() promises this */
     if (display[n])
 	displaynum = atoi(display + n + 1);
     else
 	displaynum = 0;		       /* sensible default */
     if (n > sizeof(host) - 1)
 	n = sizeof(host) - 1;
-    if (n > 0) {
-	strncpy(host, display, n);
-	host[n] = '\0';
+    strncpy(host, display, n);
+    host[n] = '\0';
+    sfree(display);
+    
+    if(!strcmp(host, "unix")) {
+	/* use AF_UNIX sockets (doesn't make sense on all platforms) */
+	addr = platform_get_x11_unix_address(displaynum,
+					     &dummy_realhost);
+	port = 0;		/* to show we are not confused */
     } else {
+	port = 6000 + displaynum;
+	
 	/*
-	 * Local display numbers, particularly on Unix, often omit
-	 * the display part completely.
+	 * Try to find host.
 	 */
-	strcpy(host, "localhost");
-    }
-
-    port = 6000 + displaynum;
-
-    /*
-     * Try to find host.
-     */
-    addr = name_lookup(host, port, &dummy_realhost, cfg);
-    if ((err = sk_addr_error(addr)) != NULL) {
-	sk_addr_free(addr);
-	return err;
+	addr = name_lookup(host, port, &dummy_realhost, cfg);
+	if ((err = sk_addr_error(addr)) != NULL) {
+	    sk_addr_free(addr);
+	    return err;
+	}
     }
 
     /*
@@ -295,7 +310,7 @@ const char *x11_init(Socket * s, char *display, void *c, void *auth,
     pr->c = c;
 
     pr->s = *s = new_connection(addr, dummy_realhost, port,
-				0, 1, 0, (Plug) pr, cfg);
+				0, 1, 0, 0, (Plug) pr, cfg);
     if ((err = sk_socket_error(*s)) != NULL) {
 	sfree(pr);
 	return err;

+ 25 - 1
putty/putty.org.h

@@ -269,7 +269,8 @@ enum {
 struct backend_tag {
     const char *(*init) (void *frontend_handle, void **backend_handle,
 			 Config *cfg,
-			 char *host, int port, char **realhost, int nodelay);
+			 char *host, int port, char **realhost, int nodelay,
+			 int keepalive);
     void (*free) (void *handle);
     /* back->reconfig() passes in a replacement configuration. */
     void (*reconfig) (void *handle, Config *cfg);
@@ -329,6 +330,7 @@ struct config_tag {
     int warn_on_close;
     int ping_interval;		       /* in seconds */
     int tcp_nodelay;
+    int tcp_keepalives;
     /* Proxy options */
     char proxy_exclude_list[512];
     int proxy_dns;
@@ -432,6 +434,8 @@ struct config_tag {
     int window_border;
     char answerback[256];
     char printer[128];
+    int arabicshaping;
+    int bidi;
     /* Colour options */
     int system_colour;
     int try_palette;
@@ -517,6 +521,11 @@ GLOBAL int flags;
 GLOBAL int default_protocol;
 GLOBAL int default_port;
 
+/*
+ * This is set TRUE by cmdline.c iff a session is loaded with "-load".
+ */
+GLOBAL int loaded_session;
+
 struct RSAKey;			       /* be a little careful of scope */
 
 /*
@@ -686,8 +695,13 @@ extern Backend telnet_backend;
  * on ssh.c.)
  */
 
+#ifdef MPEXT
 GLOBAL int (*ssh_get_line) (void *frontend, const char *prompt, char *str, int maxlen,
                             int is_pw);
+#else
+GLOBAL int (*ssh_get_line) (const char *prompt, char *str, int maxlen,
+			    int is_pw);
+#endif
 GLOBAL int ssh_getline_pw_only;
 extern Backend ssh_backend;
 
@@ -834,6 +848,16 @@ struct controlbox;
 void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 		      int midsession, int protocol);
 
+/*
+ * Exports from minibidi.c.
+ */
+typedef struct bidi_char {
+    wchar_t origwc, wc;
+    unsigned short index;
+} bidi_char;
+int do_bidi(bidi_char *line, int count);
+int do_shape(bidi_char *line, bidi_char *to, int count);
+
 /*
  * X11 auth mechanisms we know about.
  */

+ 3 - 0
resource/TextsCore.h

@@ -111,6 +111,9 @@
 #define SFTP_PACKET_TOO_BIG_INIT_EXPLAIN 205
 #define PRESERVE_TIME_PERM_ERROR 206
 #define ACCESS_VIOLATION_ERROR  207
+#define SFTP_STATUS_NO_SPACE_ON_FILESYSTEM 208
+#define SFTP_STATUS_QUOTA_EXCEEDED 209
+#define SFTP_STATUS_UNKNOWN_PRINCIPLE 210
 
 #define CORE_CONFIRMATION_STRINGS 300
 #define CONFIRM_PROLONG_TIMEOUT 301

+ 10 - 7
resource/TextsCore1.rc

@@ -66,12 +66,12 @@ BEGIN
   SFTP_STATUS_EOF, "Unexpected EOF response."
   SFTP_STATUS_NO_SUCH_FILE, "No such file or directory."
   SFTP_STATUS_PERMISSION_DENIED, "Permission denied."
-  SFTP_STATUS_FAILURE, "General failure."
+  SFTP_STATUS_FAILURE, "General failure (server should provide error description)."
   SFTP_STATUS_BAD_MESSAGE, "Bad message (badly formatted packet or protocol incompatibility)."
   SFTP_STATUS_NO_CONNECTION, "No connection."
   SFTP_STATUS_CONNECTION_LOST, "Connection lost."
-  SFTP_STATUS_OP_UNSUPPORTED, "Operation unsupported."
-  SFTP_ERROR_FORMAT, "%s\nError code: %d\nError message from server: %s (%s)\nRequest code: %d"
+  SFTP_STATUS_OP_UNSUPPORTED, "The server does not support the operation."
+  SFTP_ERROR_FORMAT, "%s\nError code: %d\nError message from server: %s %s\nRequest code: %d"
   SFTP_STATUS_UNKNOWN, "Unknown status code."
   READ_SYMLINK_ERROR, "Error reading symlink '%s'."
   EMPTY_DIRECTORY, "Server returned empty listing for directory '%s'."
@@ -92,10 +92,10 @@ BEGIN
   SFTP_INVALID_EOL, "Server requires unsupported end-of-line sequence (%s)."
   SFTP_UNKNOWN_FILE_TYPE, "Unknown file type (%d)"
   SFTP_STATUS_INVALID_HANDLE, "Invalid handle."
-  SFTP_STATUS_NO_SUCH_PATH, "No such path."
+  SFTP_STATUS_NO_SUCH_PATH, "The file path does not exist or is invalid."
   SFTP_STATUS_FILE_ALREADY_EXISTS, "File already exists."
-  SFTP_STATUS_WRITE_PROTECT, "Write protect."
-  SFTP_STATUS_NO_MEDIA, "No media."
+  SFTP_STATUS_WRITE_PROTECT, "The file is on read-only media, or the media is write protected."
+  SFTP_STATUS_NO_MEDIA, "There is no media available in the drive."
   DECODE_UTF_ERROR, "Error decoding UTF-8 string."
   CUSTOM_COMMAND_ERROR, "Error executing custom command '%s' on file '%s'."
   LOCALE_LOAD_ERROR, "Cannot load locale %d."
@@ -108,6 +108,9 @@ BEGIN
   SFTP_PACKET_TOO_BIG_INIT_EXPLAIN, "%s\n \nThe error is typically caused by message printed from startup script (like .profile). The message may start with \"%s\"."
   PRESERVE_TIME_PERM_ERROR, "Upload of file '%s' was successful, but error occurred while setting the permissions and/or timestamp. If the problem persists, turn off 'Set permissions' and/or 'Preserve timestamp' option."
   ACCESS_VIOLATION_ERROR, "Invalid access to memory"
+  SFTP_STATUS_NO_SPACE_ON_FILESYSTEM, "There is no free space on the filesystem."
+  SFTP_STATUS_QUOTA_EXCEEDED, "Operation cannot be completed because the it would exceed the users storage quota."
+  SFTP_STATUS_UNKNOWN_PRINCIPLE, "Unknown principle: %s"
 
   CORE_CONFIRMATION_STRINGS, "CORE_CONFIRMATION"
   CONFIRM_PROLONG_TIMEOUT, "Host hasn't answered for %d seconds.\n\nWait for another %0:d seconds? Pressing 'Abort' button will close session."
@@ -144,7 +147,7 @@ BEGIN
 
   CORE_VARIABLE_STRINGS, "CORE_VARIABLE"
   PUTTY_BASED_ON, "SSH and SCP code based on PuTTY %s"
-  PUTTY_VERSION, "0.54"
+  PUTTY_VERSION, "0.55"
   PUTTY_COPYRIGHT, "Copyright © 1997-2004 Simon Tatham"
   PUTTY_URL, "http://www.chiark.greenend.org.uk/~sgtatham/putty/"
 END

Some files were not shown because too many files changed in this diff