From 6bb48bf34fa77c3efb7ee166551dee2ed63c35a0 Mon Sep 17 00:00:00 2001
From: joost <joost@cnoc.nl>
Date: Sun, 18 Jun 2017 21:54:42 +0000
Subject: [PATCH]  * Propagate the result of download-actions to avoid stale
 empty files

git-svn-id: trunk@36530 -
---
 packages/fppkg/src/pkgcommands.pp |  4 +--
 packages/fppkg/src/pkgdownload.pp | 51 ++++++++++++++++++-------------
 packages/fppkg/src/pkgfphttp.pp   |  9 ++++--
 packages/fppkg/src/pkgwget.pp     | 24 +++++++++------
 utils/fppkg/pkglnet.pp            | 22 ++++++++-----
 5 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/packages/fppkg/src/pkgcommands.pp b/packages/fppkg/src/pkgcommands.pp
index cbcbac1f5e..9da6429775 100644
--- a/packages/fppkg/src/pkgcommands.pp
+++ b/packages/fppkg/src/pkgcommands.pp
@@ -255,13 +255,13 @@ begin
      (PackageManager.Options.GlobalSection.RemoteRepository='auto') then
     begin
       Log(llCommands,SLogDownloading,[PackageManager.Options.GlobalSection.RemoteMirrorsURL,PackageManager.Options.GlobalSection.LocalMirrorsFile]);
-      DownloadFile(PackageManager.Options.GlobalSection.RemoteMirrorsURL,PackageManager.Options.GlobalSection.LocalMirrorsFile, PackageManager);
+      Result := DownloadFile(PackageManager.Options.GlobalSection.RemoteMirrorsURL,PackageManager.Options.GlobalSection.LocalMirrorsFile, PackageManager);
       PackageManager.LoadLocalAvailableMirrors;
     end;
   // Download packages.xml
   PackagesURL:=PackageManager.GetRemoteRepositoryURL(PackagesFileName);
   Log(llCommands,SLogDownloading,[PackagesURL,PackageManager.Options.GlobalSection.LocalPackagesFile]);
-  DownloadFile(PackagesURL,PackageManager.Options.GlobalSection.LocalPackagesFile,PackageManager);
+  Result := Result and DownloadFile(PackagesURL,PackageManager.Options.GlobalSection.LocalPackagesFile,PackageManager);
   // Read the repository again
   PackageManager.ScanAvailablePackages;
   // no need to log errors again
diff --git a/packages/fppkg/src/pkgdownload.pp b/packages/fppkg/src/pkgdownload.pp
index 966b8ee192..dc6ba88e11 100644
--- a/packages/fppkg/src/pkgdownload.pp
+++ b/packages/fppkg/src/pkgdownload.pp
@@ -16,12 +16,12 @@ Type
     FBackupFile : Boolean;
   Protected
     // Needs overriding.
-    Procedure FTPDownload(Const URL : String; Dest : TStream); Virtual;
-    Procedure HTTPDownload(Const URL : String; Dest : TStream); Virtual;
-    Procedure FileDownload(Const URL : String; Dest : TStream); Virtual;
+    function FTPDownload(Const URL : String; Dest : TStream): Boolean; Virtual;
+    function HTTPDownload(Const URL : String; Dest : TStream): Boolean; Virtual;
+    function FileDownload(Const URL : String; Dest : TStream): Boolean; Virtual;
   Public
-    Procedure Download(Const URL,DestFileName : String);
-    Procedure Download(Const URL : String; Dest : TStream);
+    function Download(Const URL,DestFileName : String): Boolean;
+    function Download(Const URL : String; Dest : TStream): Boolean;
     Property BackupFiles : Boolean Read FBackupFile Write FBackupFile;
   end;
   TBaseDownloaderClass = Class of TBaseDownloader;
@@ -36,7 +36,7 @@ Type
 procedure RegisterDownloader(const AName:string;Downloaderclass:TBaseDownloaderClass);
 function GetDownloader(const AName:string):TBaseDownloaderClass;
 
-procedure DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg);
+function DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg): Boolean;
 
 
 implementation
@@ -72,14 +72,14 @@ begin
 end;
 
 
-procedure DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg);
+function DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg): Boolean;
 var
   DownloaderClass : TBaseDownloaderClass;
 begin
   DownloaderClass:=GetDownloader(PackageManager.Options.GlobalSection.Downloader);
   with DownloaderClass.Create(nil) do
     try
-      Download(RemoteFile,LocalFile);
+      Result := Download(RemoteFile,LocalFile);
     finally
       Free;
     end;
@@ -88,72 +88,81 @@ end;
 
 { TBaseDownloader }
 
-procedure TBaseDownloader.FTPDownload(const URL: String; Dest: TStream);
+function TBaseDownloader.FTPDownload(Const URL: String; Dest: TStream): Boolean;
 begin
   Error(SErrNoFTPDownload);
+  Result := False;
 end;
 
-procedure TBaseDownloader.HTTPDownload(const URL: String; Dest: TStream);
+function TBaseDownloader.HTTPDownload(Const URL: String; Dest: TStream): Boolean;
 begin
   Error(SErrNoHTTPDownload);
+  Result := False;
 end;
 
-procedure TBaseDownloader.FileDownload(const URL: String; Dest: TStream);
+function TBaseDownloader.FileDownload(Const URL: String; Dest: TStream): Boolean;
 
 Var
   FN : String;
   F : TFileStream;
 
 begin
+  Result := False;
   URIToFilename(URL,FN);
   If Not FileExists(FN) then
     Error(SErrNoSuchFile,[FN]);
   F:=TFileStream.Create(FN,fmOpenRead);
   Try
     Dest.CopyFrom(F,0);
+    Result := True;
   Finally
     F.Free;
   end;
 end;
 
-procedure TBaseDownloader.Download(const URL, DestFileName: String);
+function TBaseDownloader.Download(Const URL, DestFileName: String): Boolean;
 
 Var
   F : TFileStream;
 
 begin
+  Result := False;
   If FileExists(DestFileName) and BackupFiles then
     BackupFile(DestFileName);
   try
     F:=TFileStream.Create(DestFileName,fmCreate);
     try
-      Download(URL,F);
+      Result := Download(URL,F);
     finally
       F.Free;
     end;
-  except
-    DeleteFile(DestFileName);
-    raise;
+  finally
+    if not Result then
+      DeleteFile(DestFileName);
   end;
 end;
 
-procedure TBaseDownloader.Download(const URL: String; Dest: TStream);
+function TBaseDownloader.Download(Const URL: String; Dest: TStream): Boolean;
 
 Var
   URI : TURI;
   P : String;
 
 begin
+  Result := False;
   URI:=ParseURI(URL);
   P:=URI.Protocol;
   If CompareText(P,'ftp')=0 then
-    FTPDownload(URL,Dest)
+    Result := FTPDownload(URL,Dest)
   else if (CompareText(P,'http')=0) or (CompareText(P,'https')=0) then
-    HTTPDownload(URL,Dest)
+    Result := HTTPDownload(URL,Dest)
   else if CompareText(P,'file')=0 then
-    FileDownload(URL,Dest)
+    Result := FileDownload(URL,Dest)
   else
-    Error(SErrUnknownProtocol,[P, URL]);
+    begin
+      Error(SErrUnknownProtocol,[P, URL]);
+      Result := False;
+    end;
 end;
 
 
diff --git a/packages/fppkg/src/pkgfphttp.pp b/packages/fppkg/src/pkgfphttp.pp
index 553d8a7207..5206fe464c 100644
--- a/packages/fppkg/src/pkgfphttp.pp
+++ b/packages/fppkg/src/pkgfphttp.pp
@@ -7,9 +7,12 @@ interface
 uses Classes,pkgdownload,pkgoptions,fprepos;
 
 Type
+
+  { TFPHTTPDownloader }
+
   TFPHTTPDownloader = Class(TBaseDownloader)
   Protected
-    Procedure HTTPDownload(Const URL : String; Dest : TStream); override;
+    function HTTPDownload(Const URL : String; Dest : TStream): Boolean; override;
  end;
 
 implementation
@@ -17,14 +20,16 @@ implementation
 uses
   sysutils,fphttpclient, pkgglobals, pkgmessages;
 
-Procedure TFPHTTPDownloader.HTTPDownload(Const URL : String; Dest : TStream);
+function TFPHTTPDownloader.HTTPDownload(Const URL: String; Dest: TStream): Boolean;
 
 begin
+  Result := False;
   With TFPHTTPClient.Create(Nil) do
     try
       AllowRedirect := True;
       Get(URL,Dest);
       Dest.Position:=0;
+      Result := True;
     finally
       Free;
     end;
diff --git a/packages/fppkg/src/pkgwget.pp b/packages/fppkg/src/pkgwget.pp
index 163348b6d4..951d3fc245 100644
--- a/packages/fppkg/src/pkgwget.pp
+++ b/packages/fppkg/src/pkgwget.pp
@@ -7,14 +7,17 @@ interface
 uses Classes,pkgdownload,pkgoptions,fprepos;
 
 Type
+
+  { TWGetDownloader }
+
   TWGetDownloader = Class(TBaseDownloader)
   Private
     FWGet : String;
   Protected
     Constructor Create(AOwner: TComponent); override;
-    Procedure WGetDownload(Const URL : String; Dest : TStream); virtual;
-    Procedure FTPDownload(Const URL : String; Dest : TStream); override;
-    Procedure HTTPDownload(Const URL : String; Dest : TStream); override;
+    function WGetDownload(Const URL : String; Dest : TStream): Boolean; virtual;
+    function FTPDownload(Const URL : String; Dest : TStream): Boolean; override;
+    function HTTPDownload(Const URL : String; Dest : TStream): Boolean; override;
  Public
     Property WGet : String Read FWGet Write FWGet;
  end;
@@ -34,13 +37,14 @@ begin
 end;
 
 
-Procedure TWGetDownloader.WGetDownload(Const URL : String; Dest : TStream);
+function TWGetDownloader.WGetDownload(Const URL: String; Dest: TStream): Boolean;
 
 Var
   Buffer : Array[0..4096] of byte;
   Count : Integer;
 
 begin
+  Result := False;
   With TProcess.Create(Self) do
     try
       CommandLine:=WGet+' -q --output-document=- '+url;
@@ -53,22 +57,24 @@ begin
           Dest.WriteBuffer(Buffer,Count);
         end;
       If (ExitStatus<>0) then
-        Error(SErrDownloadFailed,['WGET',URL,Format('exit status %d',[ExitStatus])]);
+        Error(SErrDownloadFailed,['WGET',URL,Format('exit status %d',[ExitStatus])])
+      else
+        Result := True;
     finally
       Free;
     end;
 end;
 
-Procedure TWGetDownloader.FTPDownload(Const URL : String; Dest : TStream);
+function TWGetDownloader.FTPDownload(Const URL: String; Dest: TStream): Boolean;
 
 begin
-  WGetDownload(URL,Dest);
+  Result := WGetDownload(URL,Dest);
 end;
 
-Procedure TWGetDownloader.HTTPDownload(Const URL : String; Dest : TStream);
+function TWGetDownloader.HTTPDownload(Const URL: String; Dest: TStream): Boolean;
 
 begin
-  WGetDownload(URL,Dest);
+  Result := WGetDownload(URL,Dest);
 end;
 
 initialization
diff --git a/utils/fppkg/pkglnet.pp b/utils/fppkg/pkglnet.pp
index 03acdc0067..11996e52ab 100644
--- a/utils/fppkg/pkglnet.pp
+++ b/utils/fppkg/pkglnet.pp
@@ -32,8 +32,8 @@ Type
     procedure OnFTPSuccess(aSocket: TLSocket; const aStatus: TLFTPStatus);
     procedure OnFTPFailure(aSocket: TLSocket; const aStatus: TLFTPStatus);
     // overrides
-    procedure FTPDownload(Const URL : String; Dest : TStream); override;
-    procedure HTTPDownload(Const URL : String; Dest : TStream); override;
+    function FTPDownload(Const URL : String; Dest : TStream): Boolean; override;
+    function HTTPDownload(Const URL: String; Dest: TStream): Boolean; override;
    public
     constructor Create(AOwner : TComponent); override;
   end;
@@ -100,8 +100,9 @@ begin
   FQuit:=True;
 end;
 
-procedure TLNetDownloader.FTPDownload(const URL: String; Dest: TStream);
+function TLNetDownloader.FTPDownload(Const URL: String; Dest: TStream): Boolean;
 begin
+  Result := False;
   FOutStream:=Dest;
   Try
     { parse URL }
@@ -115,9 +116,11 @@ begin
       FFTP.CallAction;
 
     if not FQuit then begin
-      FFTP.Authenticate(URI.Username, URI.Password);
-      FFTP.ChangeDirectory(URI.Path);
-      FFTP.Retrieve(URI.Document);
+      Result := FFTP.Authenticate(URI.Username, URI.Password);
+      if Result then
+        Result := FFTP.ChangeDirectory(URI.Path);
+      if Result then
+        Result := FFTP.Retrieve(URI.Document);
       while not FQuit do
         FFTP.CallAction;
     end;
@@ -126,8 +129,9 @@ begin
   end;
 end;
 
-procedure TLNetDownloader.HTTPDownload(const URL: String; Dest: TStream);
+function TLNetDownloader.HTTPDownload(Const URL: String; Dest: TStream): Boolean;
 begin
+  Result := False;
   FOutStream:=Dest;
   Try
     { parse aURL }
@@ -146,7 +150,9 @@ begin
     while not FQuit do
       FHTTP.CallAction;
     if FHTTP.Response.Status<>HSOK then
-      Error(SErrDownloadFailed,['HTTP',EncodeURI(URI),FHTTP.Response.Reason]);
+      Error(SErrDownloadFailed,['HTTP',EncodeURI(URI),FHTTP.Response.Reason])
+    else
+      Result := True;
   Finally
     FOutStream:=nil; // to be sure
   end;