summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--UConfig.pas4
-rw-r--r--UConnectionManager.pas6
-rw-r--r--UCore.pas503
-rw-r--r--UEngines.pas8
-rw-r--r--UGnome.pas36
-rw-r--r--ULogin.pas146
-rw-r--r--UMain.pas95
-rw-r--r--USearch.pas4
-rw-r--r--USetPassword.pas107
-rw-r--r--tuxcmd.dpr2
-rw-r--r--vfs/UVFSCore.pas112
-rw-r--r--vfs/uVFSprototypes.pas75
13 files changed, 453 insertions, 651 deletions
diff --git a/.gitignore b/.gitignore
index c464bc8..73e21a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,12 @@
*.desk
*.lpi
*.kof
-*.pas~
+*.*~
*.so
+tuxcmd
+fpcver.inc
+
Copy-rules.txt
Copy.txt
ToDo-NextGen.txt
@@ -15,4 +18,3 @@ ToDo-Target-Next_Version.txt
ToDo-VFS.txt
ToDo-VFS2.txt
Todo.txt
-fpcver.inc
diff --git a/UConfig.pas b/UConfig.pas
index 9ef8917..343f281 100644
--- a/UConfig.pas
+++ b/UConfig.pas
@@ -25,8 +25,8 @@ uses Classes, ULocale;
resourcestring
ConstAppTitle = 'Tux Commander';
- ConstAboutVersion = '0.6.53-dev';
- ConstAboutBuildDate = '2008-10-12';
+ ConstAboutVersion = '0.6.54-dev';
+ ConstAboutBuildDate = '2008-10-28';
{$IFDEF FPC}
{$INCLUDE fpcver.inc}
diff --git a/UConnectionManager.pas b/UConnectionManager.pas
index 90db1e7..86f3bd7 100644
--- a/UConnectionManager.pas
+++ b/UConnectionManager.pas
@@ -360,7 +360,7 @@ begin
end;
end;
-function vfs_ask_password_callback(const AMessage: PChar; const default_user: PChar; const default_domain: PChar; flags: TVFSAskPasswordFlags;
+function vfs_ask_password_callback(const AMessage: PChar; const default_user: PChar; const default_domain: PChar; const default_password: PChar; flags: TVFSAskPasswordFlags;
username, password: PPChar; anonymous: PInteger; domain: PPChar; password_save: PVFSPasswordSave;
user_data: Pointer): LongBool; cdecl;
var ConnMgr: TFConnectionManager;
@@ -387,7 +387,7 @@ begin
if (password_save <> nil) { and ConfGnomeKeyringEnabled} then password_save^ := VFS_PASSWORD_SAVE_PERMANENTLY;
end else begin
// Show password dialog and continue in loop
- Result := HandleVFSAskPasswordCallback(DialogParent, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
+ Result := HandleVFSAskPasswordCallback(DialogParent, AMessage, default_user, default_domain, default_password, flags, username, password, anonymous, domain, password_save);
if ConnMgr is TFConnectionManager then begin
ConnMgr.FSilenceError := Result = False;
// Save password back to Connection Manager
@@ -452,7 +452,7 @@ begin
Application.ProcessMessages;
FVFSAskPasswordTry := 0;
- b := Engine.VFSOpenURI(UTF8ToStr(FActiveConnInfo.GetURI(False)), @vfs_ask_question_callback, @vfs_ask_password_callback, Self);
+ b := Engine.VFSOpenURI(UTF8ToStr(FActiveConnInfo.GetURI(False)), @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self);
AFRemoteWait.Free;
AFRemoteWait := nil;
diff --git a/UCore.pas b/UCore.pas
index 5415535..86e896b 100644
--- a/UCore.pas
+++ b/UCore.pas
@@ -28,7 +28,42 @@ function MakeDirectory(ListView: TGTKListView; Engine: TPanelEngine; LeftPanel:
procedure FindNextSelected(ListView: TGTKListView; DataList: TList; var Item1, Item2: string);
procedure UnselectAll(ListView: TGTKListView; DataList: TList);
-type TWorkerThread = class(TThread)
+
+type TVFSCallbackThread = class(TThread)
+ private
+ FThreadID: __pthread_t;
+ FCopyProgressFunc: TEngineProgressFunc;
+ procedure PrepareExecute; // Call this right after thread has been started
+ public
+ AEngine: TPanelEngine;
+ APlugin: TVFSPlugin;
+
+ VFSCallbackEvent: TSimpleEvent;
+ VFSAskQuestion_Message: PChar;
+ VFSAskQuestion_Choices: PPChar;
+ VFSAskQuestion_Choice: PInteger;
+ VFSAskQuestion_Display: boolean;
+
+ VFSAskPassword_Message: PChar;
+ VFSAskPassword_default_user: PChar;
+ VFSAskPassword_default_domain: PChar;
+ VFSAskPassword_default_password: PChar;
+ VFSAskPassword_flags: TVFSAskPasswordFlags;
+ VFSAskPassword_username: PPChar;
+ VFSAskPassword_password: PPChar;
+ VFSAskPassword_anonymous: PInteger;
+ VFSAskPassword_domain: PPChar;
+ VFSAskPassword_password_save: PVFSPasswordSave;
+ VFSAskPassword_Display: boolean;
+ VFSAskPassword_Result: LongBool;
+
+ VFSCallbackCancelled: boolean;
+
+ constructor Create(CreateSuspended: boolean);
+ destructor Destroy; override;
+ end;
+
+ TWorkerThread = class(TVFSCallbackThread)
private
FCancelled: boolean;
GUIMutex: TCriticalSection;
@@ -119,15 +154,12 @@ type TWorkerThread = class(TThread)
procedure CancelIt;
end;
- TOpenDirThread = class(TThread)
+ TOpenDirThread = class(TVFSCallbackThread)
private
- FThreadID: __pthread_t;
function ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): integer;
protected
procedure Execute; override;
public
- AEngine: TPanelEngine;
- xEngine: TVFSEngine;
APath: string;
ASelItem: string;
AAutoFallBack: boolean;
@@ -135,35 +167,12 @@ type TWorkerThread = class(TThread)
ChDirResult, ListingResult, VFSOpenResult: integer;
Finished, CancelIt: boolean;
RunningTime: Int64;
- APlugin: TVFSPlugin;
AFullPath, AHighlightItem: string;
- Password: string;
-
- VFSCallbackEvent: TSimpleEvent;
- VFSAskQuestion_Message: PChar;
- VFSAskQuestion_Choices: PPChar;
- VFSAskQuestion_Choice: PInteger;
- VFSAskQuestion_Display: boolean;
-
- VFSAskPassword_Message: PChar;
- VFSAskPassword_default_user: PChar;
- VFSAskPassword_default_domain: PChar;
- VFSAskPassword_flags: TVFSAskPasswordFlags;
- VFSAskPassword_username: PPChar;
- VFSAskPassword_password: PPChar;
- VFSAskPassword_anonymous: PInteger;
- VFSAskPassword_domain: PPChar;
- VFSAskPassword_password_save: PVFSPasswordSave;
- VFSAskPassword_Display: boolean;
- VFSAskPassword_Result: LongBool;
-
- VFSCallbackCancelled: boolean;
constructor Create;
destructor Destroy; override;
end;
-
// Thread aware functions (also half-thread-safe) without any piece of GTK code
procedure DeleteFilesWorker(SenderThread: TWorkerThread);
procedure CopyFilesWorker(SenderThread: TWorkerThread);
@@ -176,7 +185,6 @@ procedure DummyThreadWorker(SenderThread: TWorkerThread);
// Classic functions - don't need progress window
function CreateSymlink(const FileName, PossibleNewName: string; Engine: TPanelEngine) : boolean;
function EditSymlink(const FileName: string; Engine: TPanelEngine) : boolean;
-function HandleLogin(Parent: TComponent; Engine: TPanelEngine; UserName, Password: string): boolean;
procedure GetDirSize(AListView: TGTKListView; Engine: TPanelEngine; DataList: TList; AllItems: boolean);
@@ -233,9 +241,152 @@ var LeftLocalEngine, RightLocalEngine: TPanelEngine;
implementation
(********************************************************************************************************************************)
uses SysUtils, DateUtils, StrUtils, UConfig, UDirDelete, UOverwrite, ULocale,
- UNewDir, UFileAssoc, USymlink, UCoreClasses, ULogin, URemoteWait, UMain, UGnome;
+ UNewDir, UFileAssoc, USymlink, UCoreClasses, URemoteWait, UMain, UGnome;
+
+
+
+
+(********************************************************************************************************************************)
+constructor TVFSCallbackThread.Create(CreateSuspended: boolean);
+begin
+ inherited Create(CreateSuspended);
+ APlugin := nil;
+ VFSCallbackEvent := TSimpleEvent.Create;
+ VFSAskQuestion_Display := False;
+ VFSAskPassword_Display := False;
+ VFSCallbackCancelled := False;
+end;
+destructor TVFSCallbackThread.Destroy;
+begin
+ VFSCallbackEvent.Free;
+ inherited Destroy;
+end;
+
+procedure TVFSCallbackThread.PrepareExecute;
+begin
+ FThreadID := pthread_self;
+ VFSCallbackCancelled := False;
+end;
+
+(********************************************************************************************************************************)
+procedure vfs_ask_question_callback(const AMessage: PChar; const Choices: PPChar; choice: PInteger; cancel_choice: Integer; user_data: Pointer); cdecl;
+var Thread: TVFSCallbackThread;
+begin
+ Thread := user_data;
+ if (Thread = nil) { or (not (Thread is TVFSCallbackThread))} then begin
+ DebugMsg(['(ERROR): vfs_ask_question_callback: user_data is not TVFSCallbackThread, exiting.']);
+ Exit;
+ end;
+
+ if pthread_self = Application.ThreadID then begin
+ DebugMsg(['!! (WARNING): vfs_ask_question_callback called from the main thread, expected spawn from a OpenDirThread']);
+ HandleVFSAskQuestionCallback(FMain.FWidget, AMessage, Choices, choice);
+ if (choice <> nil) then Thread.VFSCallbackCancelled := (choice^ < 0) or (choice^ = cancel_choice);
+ Exit;
+ end;
+
+ if pthread_self = Thread.FThreadID then begin
+ DebugMsg(['******* vfs_ask_question_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
+ Thread.VFSAskQuestion_Message := AMessage;
+ Thread.VFSAskQuestion_Choices := Choices;
+ Thread.VFSAskQuestion_Choice := choice;
+ Thread.VFSAskQuestion_Display := True;
+ Thread.VFSCallbackEvent.ResetEvent;
+ Thread.VFSCallbackEvent.WaitFor(INFINITE);
+ DebugMsg(['******* thread: resuming...']);
+ if (choice <> nil) then Thread.VFSCallbackCancelled := (choice^ < 0) or (choice^ = cancel_choice);
+ Exit;
+ end;
+
+ DebugMsg(['!! (ERROR): vfs_ask_question_callback spawned neither from the main thread nor from active OpenDirThread, dropping the callback to prevent data corruption.']);
+ DebugMsg([' ThreadID = 0x', IntToHex(pthread_self, 16), ', OpenDirThread ID = 0x', IntToHex(Thread.FThreadID, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
+end;
+
+function vfs_ask_password_callback(const AMessage: PChar; const default_user: PChar; const default_domain: PChar; const default_password: PChar; flags: TVFSAskPasswordFlags;
+ username, password: PPChar; anonymous: PInteger; domain: PPChar; password_save: PVFSPasswordSave;
+ user_data: Pointer): LongBool; cdecl;
+var Thread: TVFSCallbackThread;
+ def_pass: PChar;
+begin
+ Result := False;
+ Thread := user_data;
+ if (Thread = nil) { or (not (Thread is TVFSCallbackThread))} then begin
+ DebugMsg(['(ERROR): vfs_ask_question_callback: user_data is not TVFSCallbackThread, exiting.']);
+ Exit;
+ end;
+
+ def_pass := default_password;
+
+ // Use stored password, if previously set
+ if ((flags and VFS_ASK_PASSWORD_ARCHIVE_MODE) = VFS_ASK_PASSWORD_ARCHIVE_MODE) and (password <> nil) and
+ (Thread.AEngine is TVFSEngine) and (Length((Thread.AEngine as TVFSEngine).Password) > 0) then
+ begin
+ if not (Thread.AEngine as TVFSEngine).PasswordUsed then begin
+ DebugMsg([' (II) vfs_ask_password_callback: reusing manually set password']);
+ password^ := g_strdup(PChar((Thread.AEngine as TVFSEngine).Password));
+ (Thread.AEngine as TVFSEngine).PasswordUsed := True;
+ Result := True;
+ Thread.VFSCallbackCancelled := False;
+ Exit;
+ end else def_pass := PChar((Thread.AEngine as TVFSEngine).Password);
+ end;
+
+ // Ask for password
+ if pthread_self = Application.ThreadID then begin
+ DebugMsg(['!! (WARNING): vfs_ask_password_callback called from the main thread, expected spawn from a OpenDirThread']);
+ Result := HandleVFSAskPasswordCallback(FMain.FWidget, AMessage, default_user, default_domain, def_pass, flags, username, password, anonymous, domain, password_save);
+ Thread.VFSCallbackCancelled := Result = False;
+ end else
+ if pthread_self = Thread.FThreadID then begin
+ DebugMsg(['******* vfs_ask_password_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
+ Thread.VFSAskPassword_Message := AMessage;
+ Thread.VFSAskPassword_default_user := default_user;
+ Thread.VFSAskPassword_default_domain := default_domain;
+ Thread.VFSAskPassword_default_password := def_pass;
+ Thread.VFSAskPassword_flags := flags;
+ Thread.VFSAskPassword_username := username;
+ Thread.VFSAskPassword_password := password;
+ Thread.VFSAskPassword_anonymous := anonymous;
+ Thread.VFSAskPassword_domain := domain;
+ Thread.VFSAskPassword_password_save := password_save;
+ Thread.VFSAskPassword_Display := True;
+ Thread.VFSAskPassword_Result := False;
+ Thread.VFSCallbackEvent.ResetEvent;
+ Thread.VFSCallbackEvent.WaitFor(INFINITE);
+ DebugMsg(['******* thread: resuming...']);
+ Result := Thread.VFSAskPassword_Result;
+ Thread.VFSCallbackCancelled := Result = False;
+ end else
+ begin
+ DebugMsg(['!! (ERROR): vfs_ask_password_callback spawned neither from the main thread nor from active OpenDirThread, dropping the callback to prevent data corruption.']);
+ DebugMsg([' ThreadID = 0x', IntToHex(pthread_self, 16), ', OpenDirThread ID = 0x', IntToHex(Thread.FThreadID, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
+ end;
+
+ // Save password back to the engine
+ if ((flags and VFS_ASK_PASSWORD_ARCHIVE_MODE) = VFS_ASK_PASSWORD_ARCHIVE_MODE) and
+ Result and (password <> nil) and (strlen(password^) > 0) and
+ (Thread.AEngine is TVFSEngine) then
+ begin
+ (Thread.AEngine as TVFSEngine).Password := string(password^);
+ (Thread.AEngine as TVFSEngine).PasswordUsed := True;
+ end;
+end;
+
+function vfs_progress_callback(position, max: Int64; user_data: Pointer): LongBool; cdecl;
+begin
+// DebugMsg(['VFSCopyCallBackFunc called (iPos = ', iPos, ', iMax = ', iMax, ')']);
+ Result := True;
+ if not Assigned(user_data) then Exit;
+
+ if Assigned(TVFSCallbackThread(user_data).FCopyProgressFunc) then
+ try
+ Result := TVFSCallbackThread(user_data).FCopyProgressFunc(user_data, position);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in vfs_progress_callback(position=', position, ', max=', max, ', user_data=', user_data, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
(********************************************************************************************************************************)
procedure ClearListData(List: TList);
@@ -586,6 +737,10 @@ end;
Exit;
end;
case ErrorType of
+ 0 : begin
+ CancelIt;
+ Exit;
+ end;
1 : s := LANGMemoryAllocationFailed;
2 : s := LANGCannotOpenSourceFile;
3 : s := LANGCannotOpenDestinationFile;
@@ -598,8 +753,9 @@ end;
else s2 := LANGMoveError;
if ErrorType <> 1 then s3 := StrToUTF8(FileName)
else s3 := '';
+
case ShowDirDeleteDialog(3, s, s3, GetErrorString(ErrorNum), s2) of
- 0 : begin // Cancel button
+ 0, 252 : begin // Cancel button, Escape
Result := False;
CancelIt;
end;
@@ -704,28 +860,48 @@ var DefResponse: integer; // Global variables for this function
begin
Result := False;
try
- with SenderThread do begin
- if ((SrcEngine is TLocalTreeEngine) and (DestEngine is TLocalTreeEngine)) or
- ((SrcEngine is TLocalTreeEngine) and (not (DestEngine is TLocalTreeEngine)))
- then Result := DestEngine.CopyFileIn(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ProgressFunc, @CopyFilesWorker_ErrorFunc, Append) else
-// DebugMsg(['2 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
- if (not (SrcEngine is TLocalTreeEngine)) and (DestEngine is TLocalTreeEngine)
- then Result := SrcEngine.CopyFileOut(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ProgressFunc, @CopyFilesWorker_ErrorFunc, Append)
- // both files are on different engines, we will have to handle the copy process ourselves
- else Result := ManualCopyFile(SourceFile, DestFile, Append);
-// DebugMsg(['3 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
-
- // If size differs, then delete target file
- if (not Append) and (not Result) then begin
-// DebugMsg(['4 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
- DataSrc := SrcEngine.GetFileInfoSL(SourceFile);
- if DataSrc = nil then Exit;
- DataDest := DestEngine.GetFileInfoSL(DestFile);
- if DataDest = nil then Exit;
- if DataSrc^.Size <> DataDest^.Size then DestEngine.Remove(DestFile);
+ with SenderThread do begin
+ AEngine := nil;
+ FCopyProgressFunc := CopyFilesWorker_ProgressFunc;
+
+ // local -> local
+ if (SrcEngine is TLocalTreeEngine) and (DestEngine is TLocalTreeEngine)
+ then Result := DestEngine.CopyFileIn(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ProgressFunc, @CopyFilesWorker_ErrorFunc, Append)
+ else
+
+ // from local engine to VFS engine
+ if (SrcEngine is TLocalTreeEngine) and (DestEngine is TVFSEngine) then
+ begin
+ AEngine := DestEngine;
+ Result := (DestEngine as TVFSEngine).CopyFileInEx(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ErrorFunc, Append,
+ @vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_progress_callback, SenderThread);
+ end else
+
+ // from VFS engine to local (most common use)
+ if (SrcEngine is TVFSEngine) and (DestEngine is TLocalTreeEngine) then
+ begin
+ AEngine := SrcEngine;
+ Result := (SrcEngine as TVFSEngine).CopyFileOutEx(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ErrorFunc, Append,
+ @vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_progress_callback, SenderThread);
+ end
+
+ // VFS to VFS (not supported yet)
+ else
+ begin
+ AEngine := SrcEngine;
+ Result := ManualCopyFile(SourceFile, DestFile, Append);
+ end;
+ AEngine := nil;
+
+ // Copy OK? (check size, otherwise delete target file)
+ if (not Append) and (not Result) then begin
+ DataSrc := SrcEngine.GetFileInfoSL(SourceFile);
+ if DataSrc = nil then Exit;
+ DataDest := DestEngine.GetFileInfoSL(DestFile);
+ if DataDest = nil then Exit;
+ if DataSrc^.Size <> DataDest^.Size then DestEngine.Remove(DestFile);
+ end;
end;
- end;
-// DebugMsg(['(II) CopyFilesWorker.LocalCopyFile: finished']);
except
on E: Exception do DebugMsg(['*** Exception raised in LocalCopyFile(SourceFile=', SourceFile, ', DestFile=', DestFile, ', Append=', Append, '): (', E.ClassName, '): ', E.Message]);
end;
@@ -2090,6 +2266,32 @@ begin
Application.ProcessMessages;
// DebugMsg(['After refresh']);
+
+ // VFS callbacks
+ if SenderThread.VFSAskQuestion_Display then begin
+ SenderThread.VFSAskQuestion_Display := False;
+ DebugMsg(['ProcessProgressThread - Main thread: displaying question dialog']);
+ HandleVFSAskQuestionCallback(ProgressForm.FWidget, SenderThread.VFSAskQuestion_Message, SenderThread.VFSAskQuestion_Choices, SenderThread.VFSAskQuestion_Choice);
+ SenderThread.VFSCallbackEvent.SetEvent;
+ end;
+ if SenderThread.VFSAskPassword_Display then begin
+ SenderThread.VFSAskPassword_Display := False;
+ DebugMsg(['ProcessProgressThread - Main thread: displaying password prompt']);
+ SenderThread.VFSAskPassword_Result := HandleVFSAskPasswordCallback(ProgressForm.FWidget,
+ SenderThread.VFSAskPassword_Message,
+ SenderThread.VFSAskPassword_default_user,
+ SenderThread.VFSAskPassword_default_domain,
+ SenderThread.VFSAskPassword_default_password,
+ SenderThread.VFSAskPassword_flags,
+ SenderThread.VFSAskPassword_username,
+ SenderThread.VFSAskPassword_password,
+ SenderThread.VFSAskPassword_anonymous,
+ SenderThread.VFSAskPassword_domain,
+ SenderThread.VFSAskPassword_password_save);
+ SenderThread.VFSCallbackEvent.SetEvent;
+ end;
+
+
try
if SenderThread.FDialogShowDirDelete then begin
AFDirDelete := nil;
@@ -2182,6 +2384,7 @@ end;
(********************************************************************************************************************************)
procedure TWorkerThread.Execute;
begin
+ PrepareExecute;
if Assigned(WorkerProcedure) then WorkerProcedure(Self);
end;
@@ -2295,6 +2498,7 @@ begin
if DirDeleteCaption = '' then FDirDeleteCaption := LANGRemoveDirectory
else FDirDeleteCaption := DirDeleteCaption;
FDialogShowDirDelete := True;
+ FCallbackLockEvent.ResetEvent;
FCallbackLockEvent.WaitFor(INFINITE);
Result := FDialogResultDirDelete;
end;
@@ -2311,6 +2515,7 @@ begin
FOverwriteSourceFile := SourceFile;
FOverwriteDestFile := DestFile;
FDialogShowOverwrite := True;
+ FCallbackLockEvent.ResetEvent;
FCallbackLockEvent.WaitFor(INFINITE);
Result := FDialogResultOverwrite;
end;
@@ -2321,6 +2526,7 @@ begin
FNewDirLabel := LabelCaption;
FNewDirEdit := Edit;
FDialogShowNewDir := True;
+ FCallbackLockEvent.ResetEvent;
FCallbackLockEvent.WaitFor(INFINITE);
Result := FDialogResultNewDir;
end;
@@ -2333,6 +2539,7 @@ begin
FMsgBoxDefault := Default;
FMsgBoxEscape := Escape;
FDialogShowMsgBox := True;
+ FCallbackLockEvent.ResetEvent;
FCallbackLockEvent.WaitFor(INFINITE);
Result := FDialogResultMsgBox;
end;
@@ -2468,29 +2675,6 @@ end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-function HandleLogin(Parent: TComponent; Engine: TPanelEngine; UserName, Password: string): boolean;
-var b: boolean;
-begin
- Result := False;
- b := Engine.Login(UserName, Password) = cVFS_OK;
- if not b then
- repeat
- try
- FLogin := TFLogin.Create(Parent);
- b := FLogin.Run = mbOK;
- UserName := FLogin.UserEntry.Text;
- Password := FLogin.PasswordEntry.Text;
- finally
- FLogin.Free;
- end;
- if not b then Exit;
- if b then b := Engine.Login(UserName, Password) = cVFS_OK;
- until b;
- Result := True;
-end;
-
-(********************************************************************************************************************************)
-(********************************************************************************************************************************)
procedure TGetDirSizeThread.Execute;
begin
Result := Engine.GetDirSize(Path);
@@ -2606,147 +2790,14 @@ begin
ListingResult := 0;
VFSOpenResult := 0;
RunningTime := 0;
- APlugin := nil;
- xEngine := nil;
- Password := '';
- VFSCallbackEvent := TSimpleEvent.Create;
- VFSAskQuestion_Display := False;
- VFSAskPassword_Display := False;
- VFSCallbackCancelled := False;
end;
destructor TOpenDirThread.Destroy;
begin
-{
- if (APlugin <> nil) and (xEngine <> nil) then
- try
- xEngine.Free;
- except
- on E: Exception do DebugMsg(['*** TOpenDirThread.Destroy -Exception: ', E.Message]);
- end;
-}
- VFSCallbackEvent.Free;
inherited Destroy;
end;
-procedure TOpenDirThread.Execute;
-var tt: TDateTime;
-begin
- FThreadID := pthread_self;
- VFSCallbackCancelled := False;
- try
-// Writeln('execute.');
- tt := Now;
- try
-// WriteLn('x1');
- if APlugin <> nil then begin
- xEngine := TVFSEngine.Create(APlugin);
- xEngine.ParentEngine := AEngine;
- xEngine.ArchiveMode := True;
- AEngine.LastHighlightItem := AHighlightItem;
- xEngine.SavePath := AEngine.Path;
- AEngine := xEngine;
- if Length(Password) > 0 then (xEngine as TVFSEngine).Password := Password;
- VFSOpenResult := (xEngine as TVFSEngine).VFSOpenEx(AFullPath);
- end else VFSOpenResult := 0;
-// WriteLn('x2');
-
- if (VFSOpenResult = 0) and (not CancelIt) then begin
-// WriteLn('x3');
- ChDirResult := ChangeDir(AEngine, APath, ASelItem, AAutoFallBack);
-// WriteLn('x4');
-
- if (ChDirResult = 0) and (not CancelIt) then begin
-// WriteLn('x5');
- ListingResult := AEngine.GetListing(ADirList, ConfShowDotFiles);
-// WriteLn('x6');
- end;
-// WriteLn('x7');
- end;
- except
- on E: Exception do DebugMsg(['*** TOpenDirThread.Execute -Exception: ', E.Message]);
- end;
- RunningTime := MilliSecondsBetween(tt, Now);
-// WriteLn('x8');
- finally
- Finished := True;
- end;
-{ except
- on E: Exception do DebugMsg(['*** Exception raised in TOpenDirThread.Execute (', E.ClassName, '): ', E.Message]);
- end; }
-end;
-
(********************************************************************************************************************************)
-procedure vfs_ask_question_callback(const AMessage: PChar; const Choices: PPChar; choice: PInteger; cancel_choice: Integer; user_data: Pointer); cdecl;
-var Thread: TOpenDirThread;
-begin
- Thread := user_data;
-
- if pthread_self = Application.ThreadID then begin
- DebugMsg(['!! (WARNING): vfs_ask_question_callback called from the main thread, expected spawn from a OpenDirThread']);
- HandleVFSAskQuestionCallback(FMain.FWidget, AMessage, Choices, choice);
- if (choice <> nil) and (Thread <> nil) and (Thread is TOpenDirThread) then Thread.VFSCallbackCancelled := (choice^ < 0) or (choice^ = cancel_choice);
- Exit;
- end;
-
- if (Thread <> nil) and (Thread is TOpenDirThread) and (pthread_self = Thread.FThreadID) then begin
- DebugMsg(['******* vfs_ask_question_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16)]);
- Thread.VFSAskQuestion_Message := AMessage;
- Thread.VFSAskQuestion_Choices := Choices;
- Thread.VFSAskQuestion_Choice := choice;
- Thread.VFSAskQuestion_Display := True;
- Thread.VFSCallbackEvent.WaitFor(INFINITE);
- DebugMsg(['******* thread: resuming...']);
- if (choice <> nil) then Thread.VFSCallbackCancelled := (choice^ < 0) or (choice^ = cancel_choice);
- Exit;
- end;
-
- DebugMsg(['!! (ERROR): vfs_ask_question_callback spawned neither from the main thread nor from active OpenDirThread, dropping the callback to prevent data corruption.']);
- if (Thread <> nil) and (Thread is TOpenDirThread)
- then DebugMsg([' ThreadID = 0x', IntToHex(pthread_self, 16), ', OpenDirThread ID = 0x', IntToHex(Thread.FThreadID, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
-end;
-
-function vfs_ask_password_callback(const AMessage: PChar; const default_user: PChar; const default_domain: PChar; flags: TVFSAskPasswordFlags;
- username, password: PPChar; anonymous: PInteger; domain: PPChar; password_save: PVFSPasswordSave;
- user_data: Pointer): LongBool; cdecl;
-var Thread: TOpenDirThread;
-begin
- Thread := user_data;
-
- if pthread_self = Application.ThreadID then begin
- DebugMsg(['!! (WARNING): vfs_ask_password_callback called from the main thread, expected spawn from a OpenDirThread']);
- Result := HandleVFSAskPasswordCallback(FMain.FWidget, AMessage, default_user, default_domain, flags, username, password, anonymous, domain, password_save);
- if (Thread <> nil) and (Thread is TOpenDirThread) then Thread.VFSCallbackCancelled := Result = False;
- Exit;
- end;
-
- if (Thread <> nil) and (Thread is TOpenDirThread) and (pthread_self = Thread.FThreadID) then begin
- DebugMsg(['******* vfs_ask_password_callback spawned, user_data = 0x', IntToHex(QWord(user_data), 16), ', ThreadID = 0x', IntToHex(pthread_self, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
- Thread.VFSAskPassword_Message := AMessage;
- Thread.VFSAskPassword_default_user := default_user;
- Thread.VFSAskPassword_default_domain := default_domain;
- Thread.VFSAskPassword_flags := flags;
- Thread.VFSAskPassword_username := username;
- Thread.VFSAskPassword_password := password;
- Thread.VFSAskPassword_anonymous := anonymous;
- Thread.VFSAskPassword_domain := domain;
- Thread.VFSAskPassword_password_save := password_save;
- Thread.VFSAskPassword_Display := True;
- Thread.VFSAskPassword_Result := False;
- Thread.VFSCallbackEvent.WaitFor(INFINITE);
- DebugMsg(['******* thread: resuming...']);
- Result := Thread.VFSAskPassword_Result;
- Thread.VFSCallbackCancelled := Result = False;
- Exit;
- end;
-
- DebugMsg(['!! (ERROR): vfs_ask_password_callback spawned neither from the main thread nor from active OpenDirThread, dropping the callback to prevent data corruption.']);
- if (Thread <> nil) and (Thread is TOpenDirThread)
- then DebugMsg([' ThreadID = 0x', IntToHex(pthread_self, 16), ', OpenDirThread ID = 0x', IntToHex(Thread.FThreadID, 16), ', Application.ThreadID = 0x', IntToHex(Application.ThreadID, 16)]);
- Result := False;
-end;
-
-
function TOpenDirThread.ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): integer;
procedure GoUp(var NewPath: string);
@@ -2778,13 +2829,13 @@ begin
// AutoFallback loop
if Engine is TVFSEngine
- then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, Self)
+ then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self)
else Error := Engine.ChangeDir(APath);
while AutoFallback and (Error <> 0) and (APath <> '/') do begin
GoUp(APath);
if Engine is TVFSEngine
- then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, Self)
+ then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self)
else Error := Engine.ChangeDir(APath);
end;
// Going on...
@@ -2803,6 +2854,38 @@ begin
end;
end;
+procedure TOpenDirThread.Execute;
+var tt: TDateTime;
+ xEngine: TVFSEngine;
+begin
+ PrepareExecute;
+ try
+ tt := Now;
+ try
+ if APlugin <> nil then begin
+ xEngine := TVFSEngine.Create(APlugin);
+ xEngine.ParentEngine := AEngine;
+ xEngine.ArchiveMode := True;
+ AEngine.LastHighlightItem := AHighlightItem;
+ xEngine.SavePath := AEngine.Path;
+ // AEngine must be set here since VFSOpenEx callbacks will reference it
+ AEngine := xEngine;
+ VFSOpenResult := (AEngine as TVFSEngine).VFSOpenEx(AFullPath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self);
+ end else VFSOpenResult := 0;
+
+ if (VFSOpenResult = 0) and (not CancelIt) then begin
+ ChDirResult := ChangeDir(AEngine, APath, ASelItem, AAutoFallBack);
+ if (ChDirResult = 0) and (not CancelIt) then
+ ListingResult := AEngine.GetListing(ADirList, ConfShowDotFiles);
+ end;
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in TOpenDirThread.Execute (', E.ClassName, '): ', E.Message]);
+ end;
+ RunningTime := MilliSecondsBetween(tt, Now);
+ finally
+ Finished := True;
+ end;
+end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
diff --git a/UEngines.pas b/UEngines.pas
index 8e8a0b8..903bec3 100644
--- a/UEngines.pas
+++ b/UEngines.pas
@@ -113,7 +113,6 @@ type
function GetPath: string; virtual; abstract;
procedure SetPath(Value: string); virtual; abstract;
function GetPrefix: string; virtual; abstract;
- function Login(Username, Password: string): integer; virtual; abstract;
// Copy-related routines
function GetBlockSize: guint32; virtual; abstract;
@@ -166,7 +165,6 @@ type
function GetPath: string; override;
procedure SetPath(Value: string); override;
function GetPrefix: string; override;
- function Login(Username, Password: string): integer; override;
function GetBlockSize: guint32; override;
procedure SetBlockSize(Value: guint32); override;
@@ -1075,12 +1073,6 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.Login(Username, Password: string): integer;
-begin
- Result := 0;
-end;
-
-(********************************************************************************************************************************)
function TLocalTreeEngine.TwoSameFiles(const Path1, Path2: string): boolean;
var st1, st2: Pstat64;
begin
diff --git a/UGnome.pas b/UGnome.pas
index dc2529c..3370e43 100644
--- a/UGnome.pas
+++ b/UGnome.pas
@@ -157,6 +157,7 @@ function HandleVFSAskPasswordCallback(DialogParent: PGtkWidget;
const AMessage: PChar;
const default_user: PChar;
const default_domain: PChar;
+ const default_password: PChar;
flags: TVFSAskPasswordFlags;
username: PPChar;
password: PPChar;
@@ -1234,7 +1235,7 @@ procedure HandleVFSAskQuestionCallback(DialogParent: PGtkWidget;
var dialog: PGtkWidget;
secondary: PChar;
primary: PChar;
- count, len: integer;
+ count, len, res: integer;
begin
len := 0;
secondary := nil;
@@ -1257,6 +1258,7 @@ begin
if primary <> nil then g_free (primary);
// gtk_window_set_title (PGtkWindow(dialog), 'VFS Question');
+ gtk_window_set_title (PGtkWindow(dialog), '');
// First count the items in the list then add the buttons in reverse order
while (TOpenPCharArray(choices)[len] <> nil)
@@ -1265,7 +1267,8 @@ begin
for count := len - 1 downto 0 do
gtk_dialog_add_button (PGtkDialog(dialog), TOpenPCharArray(choices)[count], count);
- choice^ := gtk_dialog_run(PGtkDialog(Dialog));
+ res := gtk_dialog_run (PGtkDialog(Dialog));
+ if choice <> nil then choice^ := res;
gtk_widget_destroy (PGtkWidget(Dialog));
end;
@@ -1289,7 +1292,7 @@ begin
end;
end;
-function pw_dialog_input_is_valid (priv: PVFSAskPasswordCallbackPriv): boolean;
+function pw_dialog_input_is_valid(priv: PVFSAskPasswordCallbackPriv): boolean;
begin
Result := entry_has_input(priv^.username_entry) and
entry_has_input(priv^.domain_entry) and
@@ -1313,7 +1316,7 @@ begin
gtk_dialog_set_response_sensitive(GTK_DIALOG (priv^.dialog), GTK_RESPONSE_OK, is_valid);
end;
-procedure pw_dialog_cycle_focus (widget: PGtkWidget; priv: PVFSAskPasswordCallbackPriv); cdecl;
+procedure pw_dialog_cycle_focus(widget: PGtkWidget; priv: PVFSAskPasswordCallbackPriv); cdecl;
var next_widget: PGtkWidget;
begin
next_widget := nil;
@@ -1327,6 +1330,12 @@ begin
then gtk_window_activate_default(GTK_WINDOW(priv^.dialog));
end;
+procedure unmask_checkbox_toggled(togglebutton: PGtkToggleButton; priv: PVFSAskPasswordCallbackPriv); cdecl;
+var active: gboolean;
+begin
+ active := gtk_toggle_button_get_active(togglebutton);
+ if priv^.password_entry <> nil then gtk_entry_set_visibility(priv^.password_entry, active);
+end;
// The following code has been stolen from gtkmountoperation.c
// Copyright (C) Christian Kellner <gicmo@gnome.org>
@@ -1334,6 +1343,7 @@ function HandleVFSAskPasswordCallback(DialogParent: PGtkWidget;
const AMessage: PChar;
const default_user: PChar;
const default_domain: PChar;
+ const default_password: PChar;
flags: TVFSAskPasswordFlags;
username: PPChar;
password: PPChar;
@@ -1370,6 +1380,7 @@ var widget: PGtkWidget;
remember_box: PGtkWidget;
priv: TVFSAskPasswordCallbackPriv;
s: PChar;
+ unmask_checkbox: PGtkWidget;
begin
FillChar(priv, sizeof(priv), 0);
radio_forget := nil;
@@ -1380,6 +1391,7 @@ begin
priv.dialog := PGtkDialog(widget);
window := PGtkWindow(widget);
// gtk_window_set_title (window, 'VFS Question');
+ gtk_window_set_title (window, '');
// Set the dialog up with HIG properties
gtk_dialog_set_has_separator (priv.dialog, False);
@@ -1391,9 +1403,13 @@ begin
gtk_window_set_resizable (window, False);
// gtk_window_set_icon_name (window, 'gtk-dialog-authentication');
+ if (flags and VFS_ASK_PASSWORD_ARCHIVE_MODE) = VFS_ASK_PASSWORD_ARCHIVE_MODE
+ then s := GTK_STOCK_OK
+ else s := PChar(LANGConnMgr_ConnectButton);
+
gtk_dialog_add_buttons (priv.dialog,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- PChar(LANGConnMgr_ConnectButton), GTK_RESPONSE_OK,
+ s, GTK_RESPONSE_OK,
nil);
gtk_dialog_set_default_response (priv.dialog, GTK_RESPONSE_OK);
@@ -1463,10 +1479,19 @@ begin
end;
if (flags and VFS_ASK_PASSWORD_NEED_PASSWORD) = VFS_ASK_PASSWORD_NEED_PASSWORD then begin
priv.password_entry := table_add_entry (table, rows, '_Password:', nil, @priv);
+ if (default_password <> nil) and (strlen(default_password) > 0) then
+ gtk_entry_set_text(priv.password_entry, default_password);
// Inc(Rows);
gtk_entry_set_visibility (GTK_ENTRY (priv.password_entry), FALSE);
end;
+ if (flags and VFS_ASK_PASSWORD_ARCHIVE_MODE) = VFS_ASK_PASSWORD_ARCHIVE_MODE then begin
+ unmask_checkbox := gtk_check_button_new_with_mnemonic (PChar(LANGFSetPassword_ShowPasswordCheckButton));
+ g_object_set(G_OBJECT(unmask_checkbox), 'can-focus', 0, nil);
+ gtk_box_pack_start (GTK_BOX (vbox), unmask_checkbox, FALSE, FALSE, 0);
+ g_signal_connect (unmask_checkbox, 'toggled', G_CALLBACK (@unmask_checkbox_toggled), @priv);
+ end;
+
if ((flags and VFS_ASK_PASSWORD_SAVING_SUPPORTED) = VFS_ASK_PASSWORD_SAVING_SUPPORTED) or
((flags and VFS_ASK_PASSWORD_SAVE_INTERNAL) = VFS_ASK_PASSWORD_SAVE_INTERNAL) then
begin
@@ -1515,6 +1540,7 @@ begin
if gtk_toggle_button_get_active(PGtkToggleButton(radio_remember)) then password_save^ := VFS_PASSWORD_SAVE_PERMANENTLY;
end;
end;
+
gtk_widget_destroy (PGtkWidget(priv.dialog));
end;
diff --git a/ULogin.pas b/ULogin.pas
deleted file mode 100644
index 8dbf5bb..0000000
--- a/ULogin.pas
+++ /dev/null
@@ -1,146 +0,0 @@
-(*
- Tux Commander - ULogin - Login dialog
- Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*)
-unit ULogin;
-
-interface
-
-uses
- glib2, gdk2, gtk2, pango, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView,
- GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses, GTKMenus,
- UCoreClasses;
-
-type
- TFLogin = class(TGTKDialog)
- TitleFrame: TGTKFrame;
- TitleLabel: TGTKLabel;
- TitleEventBox: TGTKEventBox;
- TitleIcon: TGTKImage;
- TitleHBox: TGTKHBox;
- Table: TGTKTable;
- Label3, Label4: TGTKLabel;
- UserEntry, PasswordEntry: TGTKEntry;
- ExperimentalWarningLabel: TGTKLabel;
- ExperimentalWarningIcon: TGTKImage;
- AnonymousCheckButton: TGTKCheckButton;
- HBox4: TGTKHBox;
- procedure FormCreate(Sender: TObject); override;
- procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
- procedure AnonymousCheckButtonToggled(Sender: TObject);
- end;
-
-var
- FLogin: TFLogin;
-
-implementation
-
-uses ULocale;
-
-
-procedure TFLogin.FormCreate(Sender: TObject);
-begin
- SetDefaultSize(200, 150);
- Caption := LANGConnLogin_Caption;
- Buttons := [mbOK, mbCancel];
- DefaultButton := mbOK;
- ShowSeparator := False;
- TitleEventBox := TGTKEventBox.Create(Self);
- TitleLabel := TGTKLabel.Create(Self);
- TitleLabel.Caption := Format('<span size="x-large" weight="ultrabold">%s</span>', [LANGConnLogin_Login]);
- TitleLabel.UseMarkup := True;
- TitleLabel.XAlign := 0;
- TitleLabel.XPadding := 0;
- TitleLabel.YPadding := 3;
- TitleEventBox.ControlState := csPrelight;
- TitleFrame := TGTKFrame.CreateWithoutLabel(Self);
- TitleFrame.ShadowType := stShadowOut;
- TitleIcon := TGTKImage.Create(Self);
- TitleIcon.SetFromStock('gtk-dialog-authentication', isLargeToolbar);
- TitleHBox := TGTKHBox.Create(Self);
- TitleHBox.Homogeneous := False;
- TitleHBox.AddControlEx(TGTKEventBox.Create(Self), False, False, 5);
- TitleHBox.AddControlEx(TitleIcon, False, False, 0);
- TitleHBox.AddControlEx(TitleLabel, True, True, 10);
- TitleEventBox.AddControl(TitleHBox);
- TitleFrame.AddControl(TitleEventBox);
- ClientArea.AddControlEx(TitleFrame, False, True, 0);
-
- HBox4 := TGTKHBox.Create(Self);
- HBox4.Homogeneous := False;
- ExperimentalWarningLabel := TGTKLabel.Create(Self);
- ExperimentalWarningLabel.Caption := LANGConnLogin_ExperimentalWarningLabelCaption;
- ExperimentalWarningLabel.UseMarkup := True;
- ExperimentalWarningLabel.LineWrap := True;
- ExperimentalWarningIcon := TGTKImage.Create(Self);
- ExperimentalWarningIcon.SetFromStock('gtk-dialog-authentication', isDialog);
- HBox4.AddControlEx(ExperimentalWarningIcon, False, False, 7);
- HBox4.AddControlEx(ExperimentalWarningLabel, True, True, 7);
- HBox4.AddControlEx(TGTKEventBox.Create(Self), False, False, 8);
-
-
- Table := TGTKTable.Create(Self);
- Table.BorderWidth := 20;
- ClientArea.AddControlEx(Table, True, True, 0);
- Table.AddControlEx(0, 0, 2, 1, HBox4, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
- Table.AddControlEx(0, 1, 2, 1, TGTKEventBox.Create(Self), [taoShrink, taoFill], [taoShrink], 5, 10);
- Label3 := TGTKLabel.Create(Self);
- Label3.XAlign := 1;
- Label3.Caption := LANGConnLogin_Username;
- UserEntry := TGTKEntry.Create(Self);
- Label3.FocusControl := UserEntry;
- Label3.UseUnderline := True;
- Label4 := TGTKLabel.Create(Self);
- Label4.XAlign := 1;
- Label4.Caption := LANGConnLogin_Password;
- PasswordEntry := TGTKEntry.Create(Self);
- PasswordEntry.Visibility := False;
- Label4.FocusControl := PasswordEntry;
- Label4.UseUnderline := True;
- AnonymousCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGConnLogin_AnonymousCheckButton);
- AnonymousCheckButton.OnToggled := AnonymousCheckButtonToggled;
- AnonymousCheckButton.Checked := False;
- Table.AddControlEx(0, 2, 1, 1, Label3, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
- Table.AddControlEx(1, 2, 1, 1, UserEntry, [taoExpand, taoFill], [taoShrink], 5, 2);
- Table.AddControlEx(0, 3, 1, 1, Label4, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
- Table.AddControlEx(1, 3, 1, 1, PasswordEntry, [taoExpand, taoFill], [taoShrink], 5, 2);
- Table.AddControlEx(0, 4, 2, 1, AnonymousCheckButton, [taoExpand, taoFill], [taoShrink], 20, 2);
-
- UserEntry.SetFocus;
- OnKeyDown := FormKeyDown;
-end;
-
-procedure TFLogin.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
-begin
- case Key of
- GDK_RETURN, GDK_KP_ENTER: ModalResult := mbOK;
- GDK_ESCAPE: ModalResult := mbCancel;
- end;
-end;
-
-procedure TFLogin.AnonymousCheckButtonToggled(Sender: TObject);
-begin
- Label3.Enabled := not AnonymousCheckButton.Checked;
- Label4.Enabled := not AnonymousCheckButton.Checked;
- UserEntry.Enabled := not AnonymousCheckButton.Checked;
- PasswordEntry.Enabled := not AnonymousCheckButton.Checked;
-end;
-
-
-end.
-
diff --git a/UMain.pas b/UMain.pas
index e214947..a808667 100644
--- a/UMain.pas
+++ b/UMain.pas
@@ -236,7 +236,6 @@ type
procedure NewTabInternal(LeftPanel: boolean; _Engine: TPanelEngine; _Path: string; NewTabPosition: integer);
procedure CopyFilenamesToClipboard(FullPaths, LeftPanel: boolean);
function HandleRunFromArchive(var APath: string; Engine: TPanelEngine; Command, FileTypeDesc: string; BypassDialog: boolean): boolean;
- function HandleSetPassword(Engine: TPanelEngine): boolean;
function HandleKey(Key: Word; Shift: TShiftState; LeftPanel: boolean): boolean;
function IsEditing(AListView: TGTKListView): boolean;
function PanelFindEditableWidget(AListView: TGTKListView): PGtkWidget;
@@ -258,7 +257,7 @@ uses ULibc,
UFileTypeSettings, UFileAssoc, UChmod, UChown, USymlink,
UPreferences, UViewer, UToolTips, UMounterPrefs, UColumns,
UTestPlugin, UConnectionManager, USearch, UProperties,
- URemoteWait, URunFromVFS, USetPassword, uVFSprototypes;
+ URemoteWait, URunFromVFS, uVFSprototypes;
@@ -1702,7 +1701,7 @@ var ListView: TGTKListView;
Engine: TPanelEngine;
s, ss: string;
i, Sel: integer;
- b, bb: boolean;
+ b: boolean;
tt: TDateTime;
DataList, DirList: TList;
SelectedFiles: TStringList;
@@ -1775,6 +1774,7 @@ var ListView: TGTKListView;
OpenDirThread.VFSAskPassword_Message,
OpenDirThread.VFSAskPassword_default_user,
OpenDirThread.VFSAskPassword_default_domain,
+ OpenDirThread.VFSAskPassword_default_password,
OpenDirThread.VFSAskPassword_flags,
OpenDirThread.VFSAskPassword_username,
OpenDirThread.VFSAskPassword_password,
@@ -1834,29 +1834,14 @@ begin
DebugMsg(['TFMain.ChangingDir: Creating thread...']);
DoThread;
- bb := OpenDirThread.VFSOpenResult = 0;
- if OpenDirThread.VFSOpenResult <> 0 then begin
- DebugMsg(['(II) TFMain.ChangingDir: OpenDirThread.VFSOpenResult <> 0']);
- if OpenDirThread.VFSOpenResult = cVFS_BadPassword then begin
- // Handle password
- if not HandleSetPassword(OpenDirThread.xEngine) then Exit;
- ss := OpenDirThread.xEngine.Password;
- if Assigned(OpenDirThread.xEngine) then OpenDirThread.xEngine.Free;
- DebugMsg(['TFMain.ChangingDir: Freeing thread...']);
- OpenDirThread.Free;
- OpenDirThread := TOpenDirThread.Create;
- DebugMsg(['TFMain.ChangingDir: Creating thread...']);
- OpenDirThread.Password := ss;
- DoThread;
- bb := OpenDirThread.VFSOpenResult = 0;
- end;
- end;
if Plugin <> nil then begin
HiliString1 := '';
HiliString2 := '';
end;
- if not bb then begin
- Application.MessageBox(LANGCouldntOpenURIArchive, [mbOK], mbError, mbOK, mbOK);
+ if OpenDirThread.VFSOpenResult <> 0 then begin
+ // Silence the error if password dialog has been cancelled
+ if not OpenDirThread.VFSCallbackCancelled then
+ Application.MessageBox(LANGCouldntOpenURIArchive, [mbOK], mbError, mbOK, mbOK);
DebugMsg(['TFMain.ChangingDir: Freeing thread...']);
OpenDirThread.Free;
end else
@@ -2649,12 +2634,6 @@ begin
end;
DebugMsg(['TFMain.DoCopyMove: NewPath = "', NewPath, '"']);
- // Handle password in archives
- if (CurrentEngine is TVFSEngine) and (CurrentEngine as TVFSEngine).GetPasswordRequired and (Length((CurrentEngine as TVFSEngine).Password) < 1) then
- if not HandleSetPassword(CurrentEngine) then Exit;
- if (OppositeEngine is TVFSEngine) and (OppositeEngine as TVFSEngine).GetPasswordRequired and (Length((OppositeEngine as TVFSEngine).Password) < 1) then
- if not HandleSetPassword(OppositeEngine) then Exit;
-
NextItem1 := ''; NextItem2 := '';
FindNextSelected(ListView, DataList, NextItem1, NextItem2);
DebugMsg(['TFMain.DoCopyMove: FindNextSelected, NextItem1 = "', NextItem1, '", NextItem2 = "', NextItem2, '"']);
@@ -3969,11 +3948,7 @@ begin
Break;
end;
- // Handle password
- if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then
- if not HandleSetPassword(Engine) then Exit;
-
- if AFile <> '' then
+ if AFile <> '' then
try
FChmod := TFChmod.Create(Self);
Stat := Engine.GetFileInfoSL(IncludeTrailingPathDelimiter(Engine.Path) + AFile);
@@ -4069,11 +4044,7 @@ begin
Break;
end;
- // Handle password
- if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then
- if not HandleSetPassword(Engine) then Exit;
-
- if AFile <> '' then
+ if AFile <> '' then
try
FChown := TFChown.Create(Self);
Stat := Engine.GetFileInfoSL(IncludeTrailingPathDelimiter(Engine.Path) + AFile);
@@ -4148,10 +4119,6 @@ begin
then s2 := IncludeTrailingPathDelimiter(EngineOpposite.Path) + PDataItem(AListView.Selected.Data)^.FName
else s2 := '';
- // Handle password
- if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then
- if not HandleSetPassword(Engine) then Exit;
-
if CreateSymlink(s1, s2, Engine) then begin
DoRefresh(LeftPanel, True, True);
DoRefresh(not LeftPanel, True, True);
@@ -4187,10 +4154,6 @@ begin
Exit;
end;
- // Handle password
- if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then
- if not HandleSetPassword(Engine) then Exit;
-
if EditSymlink(IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName, Engine) then begin
DoRefresh(LeftPanel, True, True);
DoRefresh(not LeftPanel, True, True);
@@ -5276,13 +5239,13 @@ begin
FTestPlugin := TFTestPlugin.Create(Self);
if (FTestPlugin.Run = mbOK) and (PluginList.Count > 0) then begin
Engine := TVFSEngine.Create(PluginList[FTestPlugin.PluginOptionMenu.ItemIndex]);
- if not Engine.VFSOpenURI(FTestPlugin.CommandEntry.Text, nil, nil, nil) then begin
+ if not Engine.VFSOpenURI(FTestPlugin.CommandEntry.Text, nil, nil, nil, nil) then begin
Application.MessageBox(LANGCouldntOpenURI, [mbOK], mbError, mbOK, mbOK);
Exit;
end;
b := True;
- if not FTestPlugin.AnonymousCheckButton.Checked then
- b := HandleLogin(FTestPlugin, Engine, FTestPlugin.UserEntry.Text, FTestPlugin.PasswordEntry.Text);
+{ if not FTestPlugin.AnonymousCheckButton.Checked then
+ b := HandleLogin(FTestPlugin, Engine, FTestPlugin.UserEntry.Text, FTestPlugin.PasswordEntry.Text); }
if b then begin
if LeftLastFocused then LeftPanelEngine := Engine
else RightPanelEngine := Engine;
@@ -6250,10 +6213,6 @@ begin
end else Res := mbYes;
if Res in [mbYes, mbNo] then begin
Result := False;
- // Handle password
- if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then
- if not HandleSetPassword(Engine) then Exit;
-
if Res = mbYes then DebugMsg(['(II) HandleRunFromArchive: Selected extract and execute single item'])
else DebugMsg(['(II) HandleRunFromArchive: Selected extract all and execute']);
s := IncludeTrailingPathDelimiter(ConfTempPath) + 'tuxcmd-XXXXXX';
@@ -6335,30 +6294,30 @@ begin
end;
procedure TFMain.PasswordButtonClick(Sender: TObject);
+var Engine: TPanelEngine;
+ Password: PChar;
begin
- if Sender = LeftPasswordButton then HandleSetPassword(LeftPanelEngine) else
- if Sender = RightPasswordButton then HandleSetPassword(RightPanelEngine);
-end;
+ if Sender = LeftPasswordButton then Engine := LeftPanelEngine else
+ if Sender = RightPasswordButton then Engine := RightPanelEngine
+ else Exit;
-function TFMain.HandleSetPassword(Engine: TPanelEngine): boolean;
-begin
- Result := False;
if not (Engine is TVFSEngine) then Exit;
try
- FSetPassword := TFSetPassword.Create(Self);
- FSetPassword.Entry.Text := TVFSEngine(Engine).Password;
- if Length(FSetPassword.Entry.Text) > 0 then FSetPassword.Entry.SelectAll;
- Result := FSetPassword.Run = mbOK;
- if Result then TVFSEngine(Engine).Password := FSetPassword.Entry.Text;
- FSetPassword.Free;
+ Password := nil;
+ if HandleVFSAskPasswordCallback(FWidget, PChar('The archive is encrypted and requires password'),
+ nil, nil, PChar(TVFSEngine(Engine).Password),
+ VFS_ASK_PASSWORD_NEED_PASSWORD or VFS_ASK_PASSWORD_ARCHIVE_MODE,
+ nil, @Password, nil, nil, nil) then
+ if Password <> nil then begin
+ TVFSEngine(Engine).Password := string(Password);
+ TVFSEngine(Engine).PasswordUsed := False;
+ g_free(Password);
+ end;
except
on E: Exception do DebugMsg(['*** Exception raised in FMain.HandleSetPassword: (', E.ClassName, '): ', E.Message]);
end;
end;
-
-
-
end.
diff --git a/USearch.pas b/USearch.pas
index 1c319d9..763dd41 100644
--- a/USearch.pas
+++ b/USearch.pas
@@ -577,7 +577,7 @@ begin
DebugMsg(['Found plugin ''', Plugin.VFSName, ''', trying to open the archive ''', archive, '''']);
AEngine := TVFSEngine.Create(Plugin);
(AEngine as TVFSEngine).ArchiveMode := True;
- b := b and ((AEngine as TVFSEngine).VFSOpenEx(archive) = 0);
+ b := b and ((AEngine as TVFSEngine).VFSOpenEx(archive, nil, nil, nil, nil) = 0);
end;
end;
end else begin
@@ -953,7 +953,7 @@ begin
xEngine.ArchiveMode := True;
xEngine.SavePath := StartDir + FileName;
FEngine := xEngine;
- VFSOpenResult := (FEngine as TVFSEngine).VFSOpenEx(IncludeTrailingPathDelimiter(StartDir) + FileName);
+ VFSOpenResult := (FEngine as TVFSEngine).VFSOpenEx(IncludeTrailingPathDelimiter(StartDir) + FileName, nil, nil, nil, nil);
if (VFSOpenResult = 0) and (not CancelIt) then Rekurze('/');
FEngine := FEngine.ParentEngine;
if not (xEngine as TVFSEngine).VFSClose then DebugMsg(['Error closing the engine...']);
diff --git a/USetPassword.pas b/USetPassword.pas
deleted file mode 100644
index cdf7fee..0000000
--- a/USetPassword.pas
+++ /dev/null
@@ -1,107 +0,0 @@
-(*
- Tux Commander - USetPassword - Password prompt dialog
- Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*)
-unit USetPassword;
-
-interface
-
-uses
- glib2, gtk2, pango, SysUtils, Types, Classes, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView,
- GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses;
-
-type
- TFSetPassword = class(TGTKDialog)
- Label1, Label2: TGTKLabel;
- DialogIcon: TGTKImage;
- Entry: TGTKEntry;
- Table: TGTKTable;
- ShowPasswordCheckButton: TGTKCheckButton;
- procedure FormCreate(Sender: TObject); override;
- procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
- procedure ShowPasswordCheckButtonClick(Sender: TObject);
- end;
-
-var
- FSetPassword: TFSetPassword;
-
-implementation
-
-uses ULocale, UFileAssoc;
-
-
-procedure TFSetPassword.FormCreate(Sender: TObject);
-begin
- SetDefaultSize(400, -1);
- Buttons := [mbOK, mbCancel];
- Caption := LANGFSetPassword_Caption;
-
- Table := TGTKTable.Create(Self);
- DialogIcon := TGTKImage.Create(Self);
- if gtk_style_lookup_icon_set(gtk_widget_get_style(FWidget), 'gtk-dialog-authentication') <> nil
- then DialogIcon.SetFromStock('gtk-dialog-authentication', isDialog)
- else DialogIcon.CopyFromPixbuf(StockLock48);
-
- Label1 := TGTKLabel.Create(Self);
- Label1.Caption := Format('<span size="x-large" weight="bold">%s</span>', [LANGFSetPassword_Label1_Caption]);
- Label1.UseMarkup := True;
- Label1.XAlign := 0;
- Label2 := TGTKLabel.Create(Self);
- Label2.Caption := LANGFSetPassword_Label2_Caption;
- Label2.LineWrap := True;
- Label2.XAlign := 0;
- Label2.SetSizeRequest(270, -1);
- Entry := TGTKEntry.Create(Self);
- Entry.Visibility := False;
- ShowPasswordCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGFSetPassword_ShowPasswordCheckButton);
- ShowPasswordCheckButton.OnToggled := ShowPasswordCheckButtonClick;
-
- Table.AddControlEx(0, 0, 2, 1, Label1, [taoExpand, taoFill], [taoShrink], 20, 3);
- Table.AddControlEx(0, 1, 1, 1, DialogIcon, [taoShrink], [taoShrink], 10, 5);
- Table.AddControlEx(1, 1, 1, 1, Label2, [taoExpand, taoFill], [taoShrink], 5, 0);
- Table.AddControlEx(0, 2, 1, 1, TGTKVBox.Create(Self), [taoShrink], [taoShrink, taoExpand, taoFill], 2, 6);
- Table.AddControlEx(0, 3, 2, 1, Entry, [taoExpand, taoFill], [taoShrink], 5, 0);
- Table.AddControlEx(0, 4, 2, 1, ShowPasswordCheckButton, [taoExpand, taoFill], [taoShrink], 15, 5);
- Table.BorderWidth := 10;
- ClientArea.AddControlEx(Table, True, True, 0);
- OnKeyDown := FormKeyDown;
- Entry.SetFocus;
-end;
-
-procedure TFSetPassword.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
-begin
- case Key of
- GDK_RETURN, GDK_KP_ENTER: ModalResult := mbOK;
- GDK_ESCAPE: ModalResult := mbCancel;
- GDK_M, GDK_Capital_M: if (Shift = [ssAlt]) then begin
- ShowPasswordCheckButton.Checked := not ShowPasswordCheckButton.Checked;
- Accept := False;
- end;
- end;
-end;
-
-procedure TFSetPassword.ShowPasswordCheckButtonClick(Sender: TObject);
-begin
- Entry.Visibility := ShowPasswordCheckButton.Checked;
-end;
-
-
-
-
-end.
-
diff --git a/tuxcmd.dpr b/tuxcmd.dpr
index 0219e50..8672177 100644
--- a/tuxcmd.dpr
+++ b/tuxcmd.dpr
@@ -60,14 +60,12 @@ uses
UVFSCore in 'vfs/UVFSCore.pas',
uVFSprototypes in 'vfs/uVFSprototypes.pas',
UToolTips in 'UToolTips.pas',
- ULogin in 'ULogin.pas',
UConnectionManager in 'UConnectionManager.pas',
UConnectionProperties in 'UConnectionProperties.pas',
USearch in 'USearch.pas',
UGlibThreads in 'UGlibThreads.pas',
URunFromVFS in 'URunFromVFS.pas',
ULibc in 'ULibc.pas',
- USetPassword in 'USetPassword.pas',
UTranslation_EN in 'translations/UTranslation_EN.pas',
UTranslation_CZ in 'translations/UTranslation_CZ.pas',
UTranslation_RU in 'translations/UTranslation_RU.pas',
diff --git a/vfs/UVFSCore.pas b/vfs/UVFSCore.pas
index ee2a6ca..8bba788 100644
--- a/vfs/UVFSCore.pas
+++ b/vfs/UVFSCore.pas
@@ -41,7 +41,6 @@ type
FVFSGetPrefix: TVFSGetPrefix;
FVFSGetFileSystemSize: TVFSGetFileSystemSize;
FVFSGetFileSystemFree: TVFSGetFileSystemFree;
- FVFSLogin: TVFSLogin;
FVFSFileExists: TVFSFileExists;
FVFSFileInfo: TVFSFileInfo;
FVFSMkDir: TVFSMkDir;
@@ -65,7 +64,6 @@ type
FVFSTwoSameFiles: TVFSTwoSameFiles;
FVFSGetExts: TVFSGetExts;
FVFSGetServices: TVFSGetServices;
- FVFSSetPassword: TVFSSetPassword;
FVFSGetPasswordRequired: TVFSGetPasswordRequired;
FVFSSetCallbacks: TVFSSetCallbacks;
public
@@ -88,23 +86,21 @@ type
FGlobs: Pointer;
FSourcePlugin: TVFSPlugin;
FBlockSize: Cardinal;
- FProgressFunc: TEngineProgressFunc;
- FSenderThread: Pointer;
BreakProcessingKind: integer;
- FPassword: string;
- procedure SetFPassword(Value: string);
public
ArchiveMode: boolean;
+ Password: string;
+ PasswordUsed: boolean;
constructor Create(SourcePlugin: TVFSPlugin);
- function VFSOpenURI(URI: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; CallbackData: Pointer): boolean;
- function VFSOpenEx(OpenFile: string): TVFSResult;
+ function VFSOpenURI(URI: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
+ function VFSOpenEx(OpenFile: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): TVFSResult;
function VFSClose: boolean;
destructor Destroy; override;
function GetListing(var List: TList; const AddDotFiles: boolean): integer; override;
function GetListing(var List: TList; const AddDotFiles: boolean; APath: string): integer; override;
function ChangeDir(const NewPath: string): integer; override;
- function ChangeDirEx(const NewPath: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; CallbackData: Pointer): integer;
+ function ChangeDirEx(const NewPath: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): integer;
function ExplicitChDir(const NewPath: string): integer; override;
function GetFileSystemSize: Int64; override;
function GetFileSystemSize(const APath: string): Int64; override;
@@ -134,21 +130,22 @@ type
function GetPath: string; override;
procedure SetPath(Value: string); override;
function GetPrefix: string; override;
- function Login(Username, Password: string): integer; override;
function GetBlockSize: Cardinal; override;
procedure SetBlockSize(Value: Cardinal); override;
function CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
function CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
+ function CopyFileInEx(Sender: Pointer; SourceFile, DestFile: string; ErrorFunc: TEngineErrorFunc; Append: boolean;
+ AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
+ function CopyFileOutEx(Sender: Pointer; SourceFile, DestFile: string; ErrorFunc: TEngineErrorFunc; Append: boolean;
+ AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
function IsOnSameFS(const Path1, Path2: string): boolean; override;
function TwoSameFiles(const Path1, Path2: string): boolean; override;
- function SetPassword(Password: string): integer;
function GetPasswordRequired: boolean;
published
property Path: string read GetPath write SetPath;
property BlockSize: Cardinal read GetBlockSize write SetBlockSize;
- property Password: string read FPassword write SetFPassword;
end;
@@ -199,7 +196,6 @@ begin
@FVFSGetPrefix := dlsym(ModuleHandle, 'VFSGetPrefix');
@FVFSGetFileSystemSize := dlsym(ModuleHandle, 'VFSGetFileSystemSize');
@FVFSGetFileSystemFree := dlsym(ModuleHandle, 'VFSGetFileSystemFree');
- @FVFSLogin := dlsym(ModuleHandle, 'VFSLogin');
@FVFSFileExists := dlsym(ModuleHandle, 'VFSFileExists');
@FVFSFileInfo := dlsym(ModuleHandle, 'VFSFileInfo');
@FVFSMkDir := dlsym(ModuleHandle, 'VFSMkDir');
@@ -223,7 +219,6 @@ begin
@FVFSTwoSameFiles := dlsym(ModuleHandle, 'VFSTwoSameFiles');
@FVFSGetExts := dlsym(ModuleHandle, 'VFSGetExts');
@FVFSGetServices := dlsym(ModuleHandle, 'VFSGetServices');
- @FVFSSetPassword := dlsym(ModuleHandle, 'VFSSetPassword');
@FVFSGetPasswordRequired := dlsym(ModuleHandle, 'VFSGetPasswordRequired');
@FVFSSetCallbacks := dlsym(ModuleHandle, 'VFSSetCallbacks');
// Initialize the extensions list
@@ -294,7 +289,8 @@ begin
ArchiveMode := False;
BreakProcessingKind := 0;
FGlobs := nil;
- FPassword := '';
+ Password := '';
+ PasswordUsed := False;
if @FSourcePlugin.FVFSNew <> nil then FGlobs := FSourcePlugin.FVFSNew(@VFSLogFunc);
end;
@@ -308,23 +304,28 @@ begin
end;
end;
-function TVFSEngine.VFSOpenURI(URI: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; CallbackData: Pointer): boolean;
+function TVFSEngine.VFSOpenURI(URI: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
begin
Result := False;
if (FGlobs <> nil) and (@FSourcePlugin.FVFSOpen <> nil) then begin
if @FSourcePlugin.FVFSSetCallbacks <> nil then
- FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, CallbackData);
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, ProgressCallback, CallbackData);
Result := FSourcePlugin.FVFSOpen(FGlobs, PChar(URI)) = cVFS_OK;
if @FSourcePlugin.FVFSSetCallbacks <> nil then
- FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil);
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil, nil);
end;
end;
-function TVFSEngine.VFSOpenEx(OpenFile: string): TVFSResult;
+function TVFSEngine.VFSOpenEx(OpenFile: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): TVFSResult;
begin
Result := cVFS_OK;
- if (FGlobs <> nil) and (@FSourcePlugin.FVFSOpen <> nil)
- then Result := FSourcePlugin.FVFSOpen(FGlobs, PChar(OpenFile));
+ if (FGlobs <> nil) and (@FSourcePlugin.FVFSOpen <> nil) then begin
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, ProgressCallback, CallbackData);
+ Result := FSourcePlugin.FVFSOpen(FGlobs, PChar(OpenFile));
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil, nil);
+ end;
end;
function TVFSEngine.VFSClose: boolean;
@@ -510,30 +511,22 @@ begin
DebugMsg(['^^VFS (II): ChangeDir end.']);
end;
-function TVFSEngine.ChangeDirEx(const NewPath: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; CallbackData: Pointer): integer;
+function TVFSEngine.ChangeDirEx(const NewPath: string; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): integer;
begin
if (FGlobs <> nil) and (@FSourcePlugin.FVFSChangeDir <> nil) then begin
if @FSourcePlugin.FVFSSetCallbacks <> nil then
- FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, CallbackData);
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, ProgressCallback, CallbackData);
Result := ChangeDir(NewPath);
if @FSourcePlugin.FVFSSetCallbacks <> nil then
- FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil);
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil, nil);
end;
end;
-
procedure TVFSEngine.SetPath(Value: string);
begin
ChangeDir(Value);
end;
-function TVFSEngine.Login(Username, Password: string): integer;
-begin
- if (FGlobs <> nil) and (@FSourcePlugin.FVFSLogin <> nil)
- then Result := FSourcePlugin.FVFSLogin(FGlobs, PChar(Username), PChar(Password))
- else Result := cVFS_OK;
-end;
-
function TVFSEngine.FileExists(const FileName: string; const Use_lstat: boolean = False): Boolean;
begin
if (FGlobs <> nil) and (@FSourcePlugin.FVFSFileExists <> nil)
@@ -840,32 +833,31 @@ end;
(********************************************************************************************************************************)
-
-function VFSCopyCallBackFunc(iPos, iMax:Int64; data: Pointer): LongBool; cdecl;
+function TVFSEngine.CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
begin
-// DebugMsg(['VFSCopyCallBackFunc called (iPos = ', iPos, ', iMax = ', iMax, ')']);
- Result := True;
- if not Assigned(data) then Exit;
- if Assigned(TVFSEngine(data).FProgressFunc) then
- try
- Result := TVFSEngine(data).FProgressFunc(TVFSEngine(data).FSenderThread, iPos);
- except
- on E: Exception do DebugMsg(['*** Exception raised in VFSCopyCallBackFunc(iPos=', iPos, ', iMax=', iMax, ', data=', data, '): (', E.ClassName, '): ', E.Message]);
- end;
+ Result := CopyFileInEx(Sender, SourceFile, DestFile, ErrorFunc, Append, nil, nil, nil, nil);
end;
function TVFSEngine.CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+begin
+ Result := CopyFileInEx(Sender, SourceFile, DestFile, ErrorFunc, Append, nil, nil, nil, nil);
+end;
+
+function TVFSEngine.CopyFileOutEx(Sender: Pointer; SourceFile, DestFile: string; ErrorFunc: TEngineErrorFunc; Append: boolean;
+ AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
var Res: TVFSResult;
begin
Result := False;
try
if @FSourcePlugin.FVFSCopyOut <> nil then begin
- FSenderThread := Sender;
- FProgressFunc := ProgressFunc;
// DebugMsg(['0 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
// DebugMsg([' Pointer(FGlobs) = 0x', IntToHex(Int64(FGlobs), 16), ', Pointer(@NewVFSCopyCallBackFunc) = 0x', IntToHex(Int64(@NewVFSCopyCallBackFunc), 16), ', Pointer(Self) = 0x', IntToHex(Int64(Self), 16)]);
try
- Res := FSourcePlugin.FVFSCopyOut(FGlobs, PChar(SourceFile), PChar(DestFile), @VFSCopyCallBackFunc, Self, Append);
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, ProgressCallback, CallbackData);
+ Res := FSourcePlugin.FVFSCopyOut(FGlobs, PChar(SourceFile), PChar(DestFile), Append);
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil, nil);
except
on E: Exception do begin
DebugMsg(['*** Exception raised in TVFSEngine.CopyFileOut(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
@@ -879,7 +871,7 @@ begin
cVFS_ReadErr: Result := ErrorFunc(Sender, 6, 0, SourceFile);
cVFS_WriteErr: Result := ErrorFunc(Sender, 7, 0, DestFile);
cVFS_mallocFailed: ErrorFunc(Sender, 1, 0, SourceFile);
- cVFS_Cancelled: Result := False;
+ cVFS_Cancelled: ErrorFunc(Sender, 0, 0, SourceFile);
end;
end else Result := False;
except
@@ -887,16 +879,19 @@ begin
end;
end;
-function TVFSEngine.CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+function TVFSEngine.CopyFileInEx(Sender: Pointer; SourceFile, DestFile: string; ErrorFunc: TEngineErrorFunc;
+ Append: boolean; AskQuestionCallback: PVFSAskQuestionCallback; AskPasswordCallback: PVFSAskPasswordCallback; ProgressCallback: PVFSProgressCallback; CallbackData: Pointer): boolean;
var Res: TVFSResult;
begin
Result := False;
try
if @FSourcePlugin.FVFSCopyIn <> nil then begin
- FSenderThread := Sender;
- FProgressFunc := ProgressFunc;
try
- Res := FSourcePlugin.FVFSCopyIn(FGlobs, PChar(SourceFile), PChar(DestFile), @VFSCopyCallBackFunc, Self, Append);
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, AskQuestionCallback, AskPasswordCallback, ProgressCallback, CallbackData);
+ Res := FSourcePlugin.FVFSCopyIn(FGlobs, PChar(SourceFile), PChar(DestFile), Append);
+ if @FSourcePlugin.FVFSSetCallbacks <> nil then
+ FSourcePlugin.FVFSSetCallbacks(FGlobs, nil, nil, nil, nil);
except
on E: Exception do begin
DebugMsg(['*** Exception raised in TVFSEngine.CopyFileIn(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
@@ -909,7 +904,7 @@ begin
cVFS_ReadErr: Result := ErrorFunc(Sender, 6, 0, SourceFile);
cVFS_WriteErr: Result := ErrorFunc(Sender, 7, 0, DestFile);
cVFS_mallocFailed: ErrorFunc(Sender, 1, 0, SourceFile);
- cVFS_Cancelled: Result := False;
+ cVFS_Cancelled: ErrorFunc(Sender, 0, 0, SourceFile);
end;
end else Result := False;
except
@@ -920,25 +915,12 @@ end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-function TVFSEngine.SetPassword(Password: string): integer;
-begin
- if @FSourcePlugin.FVFSSetPassword <> nil then Result := FSourcePlugin.FVFSSetPassword(FGlobs, PChar(Password))
- else Result := 0;
- FPassword := Password;
-end;
-
function TVFSEngine.GetPasswordRequired: boolean;
begin
if @FSourcePlugin.FVFSGetPasswordRequired <> nil then Result := FSourcePlugin.FVFSGetPasswordRequired(FGlobs)
else Result := False;
end;
-procedure TVFSEngine.SetFPassword(Value: string);
-begin
- SetPassword(Value);
-end;
-
-
(********************************************************************************************************************************)
(********************************************************************************************************************************)
function GetBinaryPath: string;
diff --git a/vfs/uVFSprototypes.pas b/vfs/uVFSprototypes.pas
index ba848e9..43190a4 100644
--- a/vfs/uVFSprototypes.pas
+++ b/vfs/uVFSprototypes.pas
@@ -69,7 +69,8 @@ const
VFS_ASK_PASSWORD_NEED_DOMAIN = 1 shl 2;
VFS_ASK_PASSWORD_SAVING_SUPPORTED = 1 shl 3; // Plugin reports if gnome-keyring is available
VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED = 1 shl 4;
- VFS_ASK_PASSWORD_SAVE_INTERNAL = 1 shl 15; // Save password into internal Connection Manager
+ VFS_ASK_PASSWORD_SAVE_INTERNAL = 1 shl 14; // Save password into internal Connection Manager
+ VFS_ASK_PASSWORD_ARCHIVE_MODE = 1 shl 15; // Callback from archive, change the UI a little bit
type
@@ -145,6 +146,38 @@ type
end;
type
+ // Return index of the choice selected or negative number when dialog has been cancelled
+ // cancel_choice: index which represents the cancellation choice. Set to -1 (e.g.) to disable this feature
+ PVFSAskQuestionCallback = ^TVFSAskQuestionCallback;
+ TVFSAskQuestionCallback = procedure (const AMessage: PChar;
+ const Choices: PPChar;
+ choice: PInteger;
+ cancel_choice: Integer;
+ user_data: Pointer); cdecl;
+
+ PVFSAskPasswordCallback = ^TVFSAskPasswordCallback;
+ // Remember to allocate passed strings separately (use strdup() when setting reply)
+ // Modules are eligible for keeping passwords during one session; calling callback again means the last password was wrong and user should enter new one
+ // Returns True (1) if succeeded or False (0) if cancelled
+ TVFSAskPasswordCallback = function (const AMessage: PChar;
+ const default_user: PChar;
+ const default_domain: PChar;
+ const default_password: PChar;
+ flags: TVFSAskPasswordFlags;
+ username: PPChar;
+ password: PPChar;
+ anonymous: PInteger;
+ domain: PPChar;
+ password_save: PVFSPasswordSave;
+ user_data: Pointer): LongBool; cdecl;
+
+ // Return False to break the operation
+ PVFSProgressCallback = ^TVFSProgressCallback;
+ TVFSProgressCallback = function (position: Int64;
+ max: Int64;
+ user_data: Pointer): LongBool; cdecl;
+
+type
// Log function which could plugin call - the application must handle the messages (e.g. write them to the stdout)
PVFSLogFunc = ^TVFSLogFunc;
TVFSLogFunc = procedure(S: PChar); cdecl;
@@ -177,8 +210,6 @@ type
TVFSOpen = function (g:TVFSGlobs; const sName: PChar): TVFSResult; cdecl;
// TODO: Opens the location (file or URI/URL)
// In case of URI, do not supply password encoded in the string; plugin will automatically spawn the TVFSAskPasswordCallback callback
- TVFSLogin = function (g:TVFSGlobs; const User, Pass: PChar): TVFSResult; cdecl;
- // TODO: Performs login to the server
TVFSClose = function (g:TVFSGlobs): TVFSResult; cdecl;
// Closes the file or connection to the server
TVFSMkDir = function (g:TVFSGlobs; const sDirName: PChar): TVFSResult; cdecl;
@@ -214,19 +245,20 @@ type
// TODO: Runs the command read from inside the archive (typically installing the rpm package)
- TVFSCopyCallBackFunc = function (iPos, iMax: Int64; data: Pointer):LongBool; cdecl;
- // Callback function used during the copy process; return False to break the copy process
-
- TVFSCopyOut = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; pCallBackProgress: TVFSCopyCallBackFunc; data: Pointer; Append: LongBool): TVFSResult; cdecl;
+ TVFSCopyOut = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; Append: LongBool): TVFSResult; cdecl;
// Performs the copy process from inside of module to the file in the local system
// (thus sSrcName is a path from inside of module and sDstName is path in the local filesystem where the file should be copied)
// The data pointer is then used to call the callback function in
// Note: if you need to transfer a file between two VFS modules, you need to do it manually - either first copy to local FS or use the Open, Read, Write functions of the module (NOTE: both VFS modules have to support these functions)
- TVFSCopyIn = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; pCallBackProgress: TVFSCopyCallBackFunc; data: Pointer; Append: LongBool): TVFSResult; cdecl;
+ TVFSCopyIn = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; Append: LongBool): TVFSResult; cdecl;
// Performs the copy process from the local filesystem into the module
+ // Prototype function for packing new files into archive
+ TVFSPack = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; CompressionLevel: integer; const Password: PChar): TVFSResult; cdecl;
+
+
// This is the set of basic functions which can manipulate with the data
// There is a TVFSFileDes object which identifies the processed file (filedescriptor)
// All these functions needs a pointer to an int variable to store the error code
@@ -253,7 +285,6 @@ type
TVFSFileInfo = function (g:TVFSGlobs; AFileName: PChar; VFSItem: PVFSItem): TVFSResult; cdecl;
// Gets a single info item without need to list a whole directory
- TVFSSetPassword = function (g:TVFSGlobs; pass: PChar): TVFSResult; cdecl;
TVFSGetPasswordRequired = function (g:TVFSGlobs): LongBool; cdecl;
/// pridat neco jako set_loglevel ??
@@ -261,29 +292,11 @@ type
//// pridat typ pluginu - jestli archive nebo protocol - prip. jeste pridat ktery protokoly je to schopno handlovat
- // Return index of the choice selected or negative number when dialog has been cancelled
- // cancel_choice: index which represents the cancellation choice. Set to -1 (e.g.) to disable this feature
- PVFSAskQuestionCallback = ^TVFSAskQuestionCallback;
- TVFSAskQuestionCallback = procedure (const AMessage: PChar;
- const Choices: PPChar;
- choice: PInteger;
- cancel_choice: Integer;
- user_data: Pointer); cdecl;
-
- PVFSAskPasswordCallback = ^TVFSAskPasswordCallback;
- // Remember to allocate passed strings separately (use strdup() when setting reply)
- TVFSAskPasswordCallback = function (const AMessage: PChar;
- const default_user: PChar;
- const default_domain: PChar;
- flags: TVFSAskPasswordFlags;
- username: PPChar;
- password: PPChar;
- anonymous: PInteger;
- domain: PPChar;
- password_save: PVFSPasswordSave;
- user_data: Pointer): LongBool; cdecl;
- TVFSSetCallbacks = procedure (g: TVFSGlobs; ask_question_callback: PVFSAskQuestionCallback; ask_password_callback: PVFSAskPasswordCallback; Data: Pointer); cdecl;
+ TVFSSetCallbacks = procedure (g: TVFSGlobs; ask_question_callback: PVFSAskQuestionCallback;
+ ask_password_callback: PVFSAskPasswordCallback;
+ progress_func: PVFSProgressCallback;
+ user_data: Pointer); cdecl;