home *** CD-ROM | disk | FTP | other *** search
- unit Cciccfrm;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, ExtCtrls, StdCtrls, Buttons, Menus, FileCtrl,
- {Winsock,} CCWSock, CCICCInf, CCICCPrf, IniFiles, Gauges;
-
- type
- { This record holds the information for a number of internet connections }
- PConnectionsRecord = ^TConnectionsRecord;
- TConnectionsRecord = record
- CProfile : string; { Connection profile; used in lists }
- CIPAddress : string; { Dotted character IP Address }
- CUserName : string; { Login name to site; can be anonym }
- CPassword : string; { Password; won't be shown }
- CStartDir : string; { Starting directory; used for FTP }
- end;
- { Array of TCR }
- CRFile = file of TConnectionsRecord; { File type for TCRec }
- TCCINetCCForm = class(TForm)
- Panel1: TPanel;
- Panel2: TPanel;
- Panel3: TPanel;
- Panel4: TPanel;
- Panel5: TPanel;
- Panel6: TPanel;
- ListBox1: TListBox;
- Panel7: TPanel;
- SpeedButton1: TSpeedButton;
- SpeedButton2: TSpeedButton;
- ListBox2: TListBox;
- ComboBox1: TComboBox;
- Button1: TButton;
- Memo1: TMemo;
- SpeedButton4: TSpeedButton;
- SpeedButton5: TSpeedButton;
- SpeedButton3: TSpeedButton;
- Panel8: TPanel;
- Label1: TLabel;
- Label2: TLabel;
- ComboBox2: TComboBox;
- Label3: TLabel;
- ComboBox3: TComboBox;
- Label4: TLabel;
- Label5: TLabel;
- OpenDialog1: TOpenDialog;
- SaveDialog1: TSaveDialog;
- PrintDialog1: TPrintDialog;
- PrinterSetupDialog1: TPrinterSetupDialog;
- FindDialog1: TFindDialog;
- ReplaceDialog1: TReplaceDialog;
- Gauge1: TGauge;
- MainMenu1: TMainMenu;
- Network1: TMenuItem;
- ViewWinsockInfo1: TMenuItem;
- Description1: TMenuItem;
- SystemStatus1: TMenuItem;
- VendorSpecific1: TMenuItem;
- N1: TMenuItem;
- ProgressInfo1: TMenuItem;
- ViewInEditWindow1: TMenuItem;
- ViewInStatusLine1: TMenuItem;
- SaveToFile1: TMenuItem;
- N2: TMenuItem;
- Exit1: TMenuItem;
- Services1: TMenuItem;
- IPAddress1: TMenuItem;
- EMail1: TMenuItem;
- FTP1: TMenuItem;
- UsenetNws1: TMenuItem;
- Files1: TMenuItem;
- Load1: TMenuItem;
- Save1: TMenuItem;
- Encoding1: TMenuItem;
- UUDecode1: TMenuItem;
- MIMEDecode1: TMenuItem;
- UUEncode1: TMenuItem;
- MIMEEncode1: TMenuItem;
- Edit1: TMenuItem;
- Cut1: TMenuItem;
- Copy1: TMenuItem;
- CopytoFile1: TMenuItem;
- Paste1: TMenuItem;
- PastefromFile1: TMenuItem;
- EMail2: TMenuItem;
- CheckMail1: TMenuItem;
- CreateNewMessage1: TMenuItem;
- ReplyToCurrentMessage1: TMenuItem;
- SendCurrentMessage1: TMenuItem;
- SendQueue1: TMenuItem;
- MailServers1: TMenuItem;
- Mailboxes1: TMenuItem;
- Correspondents1: TMenuItem;
- TrashMarkedMessages1: TMenuItem;
- EmptyTrash1: TMenuItem;
- ExitEMailRequired1: TMenuItem;
- FTP2: TMenuItem;
- ConnectToSite1: TMenuItem;
- Disconnect1: TMenuItem;
- UploadMarked1: TMenuItem;
- ASCII1: TMenuItem;
- Binary1: TMenuItem;
- DownloadMarked1: TMenuItem;
- ASCII2: TMenuItem;
- ToFile1: TMenuItem;
- ToDisplay1: TMenuItem;
- Binary2: TMenuItem;
- Directory1: TMenuItem;
- ViewRemoteasText1: TMenuItem;
- ViewasText1: TMenuItem;
- Change1: TMenuItem;
- Create1: TMenuItem;
- Delete3: TMenuItem;
- ChangeLocal1: TMenuItem;
- DeleteRemoteFiles1: TMenuItem;
- FTPSites1: TMenuItem;
- News1: TMenuItem;
- ConnectandUpdate1: TMenuItem;
- Disconnect2: TMenuItem;
- Headers1: TMenuItem;
- RetrieveMarked1: TMenuItem;
- RetrieveAll1: TMenuItem;
- CheckNewNews1: TMenuItem;
- GetMarked1: TMenuItem;
- Article1: TMenuItem;
- NewArticle1: TMenuItem;
- FollowupArticle1: TMenuItem;
- PutinQueue1: TMenuItem;
- Post1: TMenuItem;
- CurrentArticle1: TMenuItem;
- EntireQueue1: TMenuItem;
- NewsServers1: TMenuItem;
- SubscribedNewsgroups1: TMenuItem;
- Trash1: TMenuItem;
- AllReadArticles1: TMenuItem;
- AllMarkedArticles1: TMenuItem;
- AllAvailableArticles1: TMenuItem;
- DownloadActiveNewsgroups1: TMenuItem;
- Preferences1: TMenuItem;
- EMail3: TMenuItem;
- FTP3: TMenuItem;
- News2: TMenuItem;
- Paths1: TMenuItem;
- procedure Exit1Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure Description1Click(Sender: TObject);
- procedure SystemStatus1Click(Sender: TObject);
- procedure VendorSpecific1Click(Sender: TObject);
- procedure ViewInEditWindow1Click(Sender: TObject);
- procedure ViewInStatusLine1Click(Sender: TObject);
- procedure SaveToFile1Click(Sender: TObject);
- procedure IPAddress1Click(Sender: TObject);
- procedure FTP1Click(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure FTPSites1Click(Sender: TObject);
- procedure FTP3Click(Sender: TObject);
- procedure ConnectToSite1Click(Sender: TObject);
- procedure Button1Click(Sender: TObject);
- procedure ViewasText1Click(Sender: TObject);
- procedure Disconnect1Click(Sender: TObject);
- procedure ToDisplay1Click(Sender: TObject);
- procedure ToFile1Click(Sender: TObject);
- procedure Change1Click(Sender: TObject);
- procedure ChangeLocal1Click(Sender: TObject);
- procedure ListBox1DblClick(Sender: TObject);
- procedure ListBox2DblClick(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- procedure EnableFTPMenus;
- procedure DisableFTPMenus;
- procedure UpdateGauge( BytesFinished , TotalToHandle : longint );
- function DoFTPConnection( PCRPointer : PConnectionsRecord ) : boolean;
- procedure DoFTPDisconnect;
- procedure ReadIniData;
- procedure WriteIniData;
- procedure LoadFTPSiteFile;
- procedure SaveFTPSiteFile;
- procedure SetupFTPSiteLists;
- procedure AddNullTermTextToMemo( TheTextToAdd : string;
- TheMemoToAddTo : TMemo );
- function AddNullTermTextToLabel( TheTextToAdd : string ) : string;
- procedure SetHGCursors;
- procedure SetNormalCursors;
- procedure AddProgressText( WhatText : string );
- procedure ShowProgressText( WhatText : string );
- procedure ShowProgressErrorText( WhatText : string );
- procedure SocketsErrorOccurred( Sender : TObject;
- ErrorCode : Integer;
- TheMessage : string );
- end;
- { Component to hold FTP handling capabilities }
- TFTPComponent = class( TWinControl )
- public
- FTPCommandInProgress ,
- Connection_Established : Boolean;
- Socket1 : TCCSocket;
- Socket2 : TCCSocket;
- constructor Create( AOwner : TComponent ); override;
- destructor Destroy; override;
- function GetTotalBytesToReceive( TheString : string ) : Longint;
- function StripBrackets( TheString : string ) : string;
- function GetShortPathname( TheString : string ) : string;
- function GetWin16FileName( InputName : string ) : string;
- function GetRemoteWorkingDirectory( var RemoteDir : string ) : Boolean;
- function SetRemoteDirectory( TheDir : string ) : Boolean;
- function EstablishConnection( PCRPointer : PConnectionsRecord ) : Boolean;
- function LoginUser( PCRPointer : PConnectionsRecord ) : Boolean;
- function SendPassword( PCRPointer : PConnectionsRecord ) : Boolean;
- function SetRemoteStartupDirectory( PCRPointer : PConnectionsRecord )
- : Boolean;
- function GetRemoteDirectoryListing( TheListBox : TListBox ) : Boolean;
- function GetRemoteDirectoryListingToMemo : Boolean;
- procedure ReceiveASCIIRemoteFile( RemoteName , LocalName : string );
- procedure ReceiveBinaryRemoteFile( RemoteName , LocalName : string );
- function GetLocalDirectoryAndListing( var TheString : string;
- TheListBox : TListBox )
- : Boolean;
- function GetUNIXTextString( var StringIn : string ) : string;
- procedure ReceiveASCIIRemoteFileToMemo( RemoteName : string );
- function GetListeningPort : Integer;
- procedure GetFileNameFromUNIXFileName( var TheName : string );
- function Disconnect : Boolean;
- function DoCStyleFormat( TheText : string;
- const TheArguments : array of const ) : string;
- procedure UpdateGauge( BytesFinished , TotalToHandle : longint );
- function GetQuotedString( TheString : string ) : string;
- procedure AddProgressText( WhatText : string );
- procedure ShowProgressText( WhatText : string );
- procedure ShowProgressErrorText( WhatText : string );
- function GetFTPServerResponse( var ResponseString : string ) : Integer;
- procedure FTPSocketsErrorOccurred( Sender : TObject;
- ErrorCode : Integer;
- TheMessage : string );
- function PerformFTPCommand(
- TheCommand : string;
- const TheArguments : array of const ) : Integer;
- end;
- const
- POV_MEMO = 1; { Progress to the Memo }
- POV_STAT = 2; { Progress to the status caption }
- FTP_STATUS_PRELIMINARY = 1; { Wait; command being processed }
- FTP_STATUS_COMPLETED = 2; { Done; command fully succeded }
- FTP_STATUS_CONTINUING = 3; { OK; send more data to finish }
- FTP_STATUS_RETRY_COMMAND = 4; { Temporary Error; try cmd again }
- FTP_STATUS_FATAL_ERROR = 5; { Fatal Error; don't retry cmd }
-
- var
- CCINetCCForm : TCCINetCCForm;
- GlobalErrorCode : Integer; { Used to pass around error info }
- GlobalAbortedFlag : Boolean; { Used to signal timeout error }
- ProgressList : TStringList; { Used to hold progress text info }
- ProgressFileName : string; { Used to hold progress file name }
- ProgressOutputVector : Integer; { Used to direct progress output }
- TheFTPSiteList : TList; { Used to store the FTP site recs }
- TheWorkingFTPSL : TList; { Used to store working copy of l }
- TheFTPSiteFile : CRFile; { Used to load the FTP site file }
- TheICCIniFile : TIniFile; { Used to retrieve the INI File }
- MailPath : string; { Used for path to Mail Files }
- NewsPath : string; { Used for path to News Files }
- WWWPath : string; { Used for path to WWW Files }
- FTPPath : string; { Used for path to FTP Files }
- CurrentPassWordString : string; { Used to hold login id for anons }
- PassWordControlVector : Integer; { Used to hold display of pw vect }
- CurrentRealPWString : string; { Used to hold a real password }
- TheFTPComponent : TFTPComponent; { FTP Object }
- TheLine ,
- HolderLine ,
- GlobalTextBuffer : string;
- TheAnonRedialVector ,
- DefaultDownloadVector : Integer;
- LeftoverText : string;
- LeftoversOnTable : Boolean;
- FileNameToXFer : string;
-
- implementation
-
- {$R *.DFM}
-
- { This is the FTP component constructor; it creates 2 sockets }
- constructor TFTPComponent.Create( AOwner : TComponent );
- begin
- { do inherited create }
- inherited Create( AOwner );
- { Create sockets, put in their parents, and error procs }
- Socket1 := TCCSocket.Create( Self );
- Socket1.Parent := Self;
- Socket1.OnErrorOccurred := FTPSocketsErrorOccurred;
- Socket2 := TCCSocket.Create( Self );
- Socket2.Parent := Self;
- Socket2.OnErrorOccurred := FTPSocketsErrorOccurred;
- { Set up booleans }
- Connection_Established := false;
- FTPCommandInProgress := false;
- end;
-
- { This is the FTP component destructor; it frees 2 sockets }
- destructor TFTPComponent.Destroy;
- begin
- { Free the sockets }
- Socket1.Free;
- Socket2.Free;
- { and call inherited }
- inherited Destroy;
- end;
-
- function TFTPComponent.GetShortPathname( TheString : string ) : string;
- var HoldingString : string;
- begin
- HoldingString := Copy( TheString , 1 , 3 );
- HoldingString := HoldingString + '..\' + ExtractFileName( TheString );
- Result := HoldingString;
- end;
-
- function TFTPComponent.StripBrackets( TheString : string ) : string;
- var HoldingString : string;
- HoldingPosition : Integer;
- begin
- HoldingPosition := Pos( '[' , TheString );
- if HoldingPosition = 0 then
- begin
- Result := TheString;
- exit;
- end
- else
- begin
- HoldingString := Copy( TheString , HoldingPosition + 1 , 255 );
- HoldingPosition := Pos( ']' , HoldingString );
- if HoldingPosition = 0 then
- begin
- Result := HoldingString;
- exit;
- end
- else
- begin
- HoldingString := Copy( HoldingString , 1 , HoldingPosition - 1 );
- Result := HoldingString;
- exit;
- end;
- end;
- end;
-
- { This function takes a UNIX filespec and turns it into a Win16 filename }
- function TFTPComponent.GetWin16FileName( InputName : string ) : string;
- var WorkingString ,
- HoldingString : string; { Holding string }
- begin
- WorkingString := ExtractFileExt( InputName );
- if WorkingString = '' then
- begin
- if Length( InputName ) > 8 then
- WorkingString := Copy( InputName , 1 , 8 ) else
- WorkingString := InputName;
- end
- else
- begin
- if Length( WorkingString ) > 4 then
- WorkingString := Copy( WorkingString , 1 , 4 );
- HoldingString :=
- Copy( InputName , 1 , Pos( WorkingString , InputName ) - 1 );
- if Length( HoldingString ) > 8 then
- HoldingString := Copy( HoldingString , 1 , 8 );
- if HoldingString = '' then
- begin
- { Dot file }
- HoldingString := Copy( InputName , 2 , 255 ) + '.TXT';
- WorkingString := HoldingString;
- end
- else WorkingString := HoldingString + WorkingString;
- end;
- Result := WorkingString;
- end;
-
-
- { This function strips out the FTP response for bytes to send }
- function TFTPComponent.GetTotalBytesToReceive( TheString : string ) : Longint;
- var
- LeftPosition ,
- RightPosition : Integer;
- TempString : string;
- begin
- LeftPosition := Pos( '(' , TheString );
- TempString := Copy( TheString ,
- LeftPosition + 1 , 255 );
- RightPosition := Pos( ' ' , TempString );
- if (( LeftPosition = 0 ) or ( RightPosition = 0 )) then
- begin
- Result := 0;
- exit;
- end;
- if RightPosition <> 0 then
- TempString := Copy( TempString , 1 , RightPosition - 1 );
- try
- Result := StrToInt( TempString );
- except
- on EConvertError do Result := 0;
- end;
- end;
-
- procedure TFTPComponent.UpdateGauge( BytesFinished , TotalToHandle : longint );
- begin
- CCInetCCForm.UpdateGauge( BytesFinished , TotalToHandle );
- end;
-
- { This sends FTP progress text to the Inet form }
- procedure TFTPComponent.AddProgressText( WhatText : string );
- begin
- CCInetCCForm.AddProgressText( WhatText );
- end;
-
- { This sends FTP progress text to the Inet form }
- procedure TFTPComponent.ShowProgressText( WhatText : string );
- begin
- CCInetCCForm.ShowProgressText( WhatText );
- end;
-
- { This procedure receives a binary remote file }
- procedure TFTPComponent.ReceiveASCIIRemoteFileToMemo( RemoteName : string );
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- InputString : string;
- Through ,
- Finished : Boolean;
- TotalBytesSent ,
- FileToGetSize : Longint;
- begin
- TheReturnString :=
- DoCStyleFormat( 'TYPE A' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- FTPCommandInProgress := false;
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP File Receive Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { leave }
- exit;
- end
- else
- begin
- { Set up socket 2 for listening }
- Socket2.AsynchMode := False;
- Socket2.NonAsynchTimeoutValue := 60;
- { do a listen and send command to server that this is receipt socket }
- if GetListeningPort = FTP_STATUS_FATAL_ERROR then
- begin
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket1.NonAsynchTimeoutValue := 0; {infinite timeout}
- TheReturnString :=
- DoCStyleFormat( 'RETR %s' ,
- [ RemoteName ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- TheResult := PerformFTPCommand( 'RETR %s' , [RemoteName] );
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- FileToGetSize := GetTotalBytesToReceive( TheReturnString );
- Socket1.NonAsynchTimeoutValue := 30;
- if (( TheResult = FTP_STATUS_RETRY_COMMAND ) or
- ( TheResult = FTP_STATUS_FATAL_ERROR )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not obtain remote file!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket2.CCSockAccept;
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not establish receive socket!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- exit;
- end;
- Through := false;
- TotalBytesSent := 0;
- repeat
- TheReturnString := Socket2.StringData;
- if Length( TheReturnString ) = 0 then Through := true;
- if Length( TheReturnString ) > 0 then
- begin
- TotalBytesSent := TotalBytesSent + Length( TheReturnString );
- UpdateGauge( TotalBytesSent , FileToGetSize );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- end;
- if GlobalAbortedFlag then
- begin
- Socket1.OutOfBand := 'ABOR'+#13#10;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- exit;
- end;
- until Through;
- { cancel listening on second socket and close it }
- Socket2.CCSockCancelListen;
- Socket2.CCSockClose;
- FTPCommandInProgress := false;
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- Through := false;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- if Pos( 'TYPE' , Uppercase( TheReturnString )) > 0 then
- Through := true;
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or Through );
- end;
- FTPCommandInProgress := false;
- end;
-
- { This procedure receives a binary remote file }
- procedure TFTPComponent.ReceiveASCIIRemoteFile( RemoteName , LocalName : string );
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- InputString : string;
- Through ,
- Finished : Boolean;
- FileNamePChar : array[ 0 .. 255 ] of char;
- OutputFileHandle : Integer;
- TotalBytesSent ,
- FileToGetSize : Longint;
- CopyBuffer : array[ 0 .. 255 ] of char;
- begin
- LocalName := ExpandFileName( LocalName );
- StrPCopy( FileNamePChar , LocalName );
- OutputFileHandle := _lcreat( FileNamePChar , 0 );
- if OutputFileHandle = -1 then
- begin
- MessageDlg( 'Cannot Create local file ' + LocalName ,
- mtError , [mbOK] , 0 );
- exit;
- end;
- TheReturnString :=
- DoCStyleFormat( 'TYPE A' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP File Receive Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { leave }
- exit;
- end
- else
- begin
- { Set up socket 2 for listening }
- Socket2.AsynchMode := False;
- Socket2.NonAsynchTimeoutValue := 60;
- { do a listen and send command to server that this is receipt socket }
- if GetListeningPort = FTP_STATUS_FATAL_ERROR then
- begin
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket1.NonAsynchTimeoutValue := 0; {infinite timeout}
- TheReturnString :=
- DoCStyleFormat( 'RETR %s' ,
- [ RemoteName ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- TheResult := PerformFTPCommand( 'RETR %s' , [RemoteName] );
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- FileToGetSize := GetTotalBytesToReceive( TheReturnString );
- Socket1.NonAsynchTimeoutValue := 30;
- if (( TheResult = FTP_STATUS_RETRY_COMMAND ) or
- ( TheResult = FTP_STATUS_FATAL_ERROR )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not obtain remote file!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket2.CCSockAccept;
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not establish receive socket!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- exit;
- end;
- Through := false;
- TotalBytesSent := 0;
- repeat
- TheReturnString := Socket2.StringData;
- if Length( TheReturnString ) = 0 then Through := true;
- if Length( TheReturnString ) > 0 then
- begin
- StrPCopy( CopyBuffer , TheReturnString );
- TotalBytesSent := TotalBytesSent + Length( TheReturnString );
- UpdateGauge( TotalBytesSent , FileToGetSize );
- if _lwrite( OutputFileHandle , CopyBuffer , Length( TheReturnString ))
- = -1 then
- begin
- MessageDlg( 'File Write Error on ' + LocalName , mtError , [mbOK] , 0 );
- GlobalAbortedFlag := True;
- end;
- end;
- if GlobalAbortedFlag then
- begin
- Socket1.OutOfBand := 'ABOR'+#13#10;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- exit;
- end;
- until Through;
- { cancel listening on second socket and close it }
- Socket2.CCSockCancelListen;
- Socket2.CCSockClose;
- FTPCommandInProgress := false;
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- Through := false;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- if Pos( 'TYPE' , Uppercase( TheReturnString )) > 0 then
- Through := true;
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or Through );
- end;
- _lclose( OutputFileHandle );
- FTPCommandInProgress := false;
- end;
-
- { This procedure receives a binary remote file }
- procedure TFTPComponent.ReceiveBinaryRemoteFile( RemoteName , LocalName : string );
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- InputString : string;
- Through ,
- Finished : Boolean;
- FileNamePChar : array[ 0 .. 255 ] of char;
- OutputFileHandle : Integer;
- TotalBytesSent ,
- FileToGetSize : Longint;
- CopyBuffer : array[ 0 .. 255 ] of char;
- begin
- LocalName := ExpandFileName( LocalName );
- StrPCopy( FileNamePChar , LocalName );
- OutputFileHandle := _lcreat( FileNamePChar , 0 );
- if OutputFileHandle = -1 then
- begin
- MessageDlg( 'Cannot Create local file ' + LocalName ,
- mtError , [mbOK] , 0 );
- exit;
- end;
- TheReturnString :=
- DoCStyleFormat( 'TYPE I' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'TYPE I',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP File Receive Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { leave }
- exit;
- end
- else
- begin
- { Set up socket 2 for listening }
- Socket2.AsynchMode := False;
- Socket2.NonAsynchTimeoutValue := 60;
- { do a listen and send command to server that this is receipt socket }
- if GetListeningPort = FTP_STATUS_FATAL_ERROR then
- begin
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket1.NonAsynchTimeoutValue := 0; {infinite timeout}
- TheReturnString :=
- DoCStyleFormat( 'RETR %s' ,
- [ RemoteName ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- TheResult := PerformFTPCommand( 'RETR %s' , [RemoteName] );
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- FileToGetSize := GetTotalBytesToReceive( TheReturnString );
- Socket1.NonAsynchTimeoutValue := 30;
- if (( TheResult = FTP_STATUS_RETRY_COMMAND ) or
- ( TheResult = FTP_STATUS_FATAL_ERROR )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not obtain remote file!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket2.CCSockAccept;
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not establish receive socket!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- exit;
- end;
- Through := false;
- TotalBytesSent := 0;
- repeat
- TheReturnString := Socket2.StringData;
- if Length( TheReturnString ) = 0 then Through := true;
- if Length( TheReturnString ) > 0 then
- begin
- StrPCopy( CopyBuffer , TheReturnString );
- TotalBytesSent := TotalBytesSent + Length( TheReturnString );
- UpdateGauge( TotalBytesSent , FileToGetSize );
- if _lwrite( OutputFileHandle , CopyBuffer , Length( TheReturnString ))
- = -1 then
- begin
- MessageDlg( 'File Write Error on ' + LocalName , mtError , [mbOK] , 0 );
- GlobalAbortedFlag := True;
- end;
- end;
- if GlobalAbortedFlag then
- begin
- Socket1.OutOfBand := 'ABOR'+#13#10;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- exit;
- end;
- until Through;
- { cancel listening on second socket and close it }
- Socket2.CCSockCancelListen;
- Socket2.CCSockClose;
- FTPCommandInProgress := false;
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- Through := false;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- if Pos( 'TYPE' , Uppercase( TheReturnString )) > 0 then
- Through := true;
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or Through );
- end;
- _lclose( OutputFileHandle );
- FTPCommandInProgress := false;
- end;
-
- { This sends FTP progress text to the Inet form }
- procedure TFTPComponent.ShowProgressErrorText( WhatText : string );
- begin
- CCInetCCForm.ShowProgressErrorText( WhatText );
- end;
-
- { This is a core function! It performs an FTP command and if no timeout }
- { return a preliminary ok. }
- function TFTPComponent.PerformFTPCommand(
- TheCommand : string;
- const TheArguments : array of const ) : Integer;
- var TheBuffer : string; { Text buffer }
- begin
- { If command in progress send back -1 error }
- if FTPCommandInProgress then
- begin
- Result := -1;
- exit;
- end;
- { Set status variable }
- FTPCommandInProgress := True;
- { Set global error code }
- GlobalErrorCode := 0;
- { Format output string }
- TheBuffer := Format( TheCommand , TheArguments );
- { Preset failure code }
- Result := FTP_STATUS_FATAL_ERROR;
- { If invalid socket or no connection abort }
- if ( Socket1.TheSocket = INVALID_SOCKET ) or not Connection_Established then
- exit;
- { Send the buffer plus EOL chars }
- Socket1.StringData := TheBuffer + #13#10;
- { if abort due to timeout or other error exit }
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
- { Otherwise return preliminary code }
- Result := FTP_STATUS_PRELIMINARY;
- end;
-
- { This function gets up to 255 chars of data plus a return code from FTP serv }
- function TFTPComponent.GetFTPServerResponse(
- var ResponseString : string ) : Integer;
- var
- { Buffer string for response line }
- TheBuffer : string;
- { Pointer to the response string }
- BufferPointer : array[0..255] of char absolute TheBuffer;
- { Character to check for response code }
- ResponseChar : char;
- { Pointers into returned string }
- TheIndex ,
- TheLength : Integer;
- { Control variable }
- LeftoversInPan ,
- Finished : Boolean;
- begin
- { Preset fatal error }
- Result := FTP_STATUS_FATAL_ERROR;
- { Start loop control }
- LeftoversInPan := false;
- Finished := false;
- repeat
- { Do a peek }
- TheBuffer := Socket1.PeekData;
- { If timeout or other error exit }
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
- { Find end of line character }
- TheIndex := Pos( #10 , TheBuffer );
- if TheIndex = 0 then
- begin
- TheIndex := Pos( #13 , TheBuffer );
- if TheIndex = 0 then
- begin
- TheIndex := Pos( #0 , TheBuffer );
- if TheIndex = 0 then
- begin
- TheIndex := Length( TheBuffer );
- LeftoversInPan := True;
- LeftoverText := LeftoverText + TheBuffer;
- LeftoversOnTable := false;
- end;
- end;
- end;
- { If an end of line then process the line }
- if TheIndex > 0 then
- begin
- { Get length of string }
- TheLength := TheIndex;
- { Receive actual data }
- Socket1.CCSockReceive( Socket1.TheSocket ,
- @BufferPointer[ 1 ] ,
- TheLength );
- { Abort if timeout or error }
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
- { Put in the length byte }
- BufferPointer[ 0 ] := Chr( TheLength );
- if LeftOversOnTable then
- begin
- LeftOversOnTable := false;
- ResponseString := LeftoverText + TheBuffer;
- TheBuffer := ResponseString;
- LeftoverText := '';
- end;
- if LeftoversInPan then
- begin
- LeftoversInPan := false;
- LeftoversOnTable := true;
- end;
- { If not a continuation line }
- if TheBuffer[ 4 ] <> '-' then
- begin
- { Get first number character }
- ResponseChar := TheBuffer[ 1 ];
- { Get the value of the number from 1 to 5 }
- if (( ResponseChar >= '1' ) and ( ResponseChar <= '5' )) then
- begin
- Finished := true;
- Result := Ord( ResponseChar ) - 48;
- end;
- end
- else
- begin
- { otherwise return preliminary result }
- Finished := true;
- Result := FTP_STATUS_PRELIMINARY;
- end;
- end
- else
- begin
- end;
- until ( Finished and ( not LeftoversOnTable ));
- { Return buffer as response string }
- ResponseString := TheBuffer;
- end;
-
- { Boilerplate error routine }
- procedure TFTPComponent.FTPSocketsErrorOccurred( Sender : TObject;
- ErrorCode : Integer;
- TheMessage : string );
- begin
- CCInetCCForm.SocketsErrorOccurred( Sender,ErrorCode,TheMessage );
- end;
-
- { This is the FTP components initial connection routine }
- function TFTPComponent.EstablishConnection(
- PCRPointer : PConnectionsRecord ) : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- { Set default FTP Port value }
- Socket1.PortName := '21';
- { Get the ip address from the record }
- Socket1.IPAddressName := PCRPointer^.CIPAddress;
- { Set blocking mode }
- Socket1.AsynchMode := False;
- { Clear condition variables }
- GlobalErrorCode := 0;
- GlobalAbortedFlag := false;
- { Actually attempt to connect }
- Socket1.CCSockConnect;
- { Check if connected }
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 ) or
- ( Socket1.TheSocket = INVALID_SOCKET )) then
- begin { Didn't connect; signal error and abort }
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host %s Connection Failed!' ,
- [ PCRPointer^.CIPAddress ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else
- begin
- Connection_Established := true;
- { Signal successful connection }
- TheReturnString := DoCStyleFormat(
- 'Connected on Local port: %s with IP: %s',
- [ Socket1.GetSocketPort( Socket1.TheSocket ),
- Socket1.GetSocketIPAddress( Socket1.TheSocket )]);
- { Put result in progress and status line }
- CCINetCCForm.AddProgressText( TheReturnString );
- CCINetCCForm.ShowProgressText( TheReturnString );
- TheReturnString := DoCStyleFormat(
- 'Connected to Remote port: %s with IP: %s',
- [ Socket1.GetSocketPeerPort( Socket1.TheSocket ),
- Socket1.GetSocketPeerIPAddress( Socket1.TheSocket )]);
- { Put result in progress and status line }
- CCINetCCForm.AddProgressText( TheReturnString );
- CCINetCCForm.ShowProgressText( TheReturnString );
- TheReturnString := DoCStyleFormat( 'Successfully connected to %s',
- [ Socket1.IPAddressName ]);
- { Put result in progress and status line }
- CCINetCCForm.AddProgressText( TheReturnString );
- CCINetCCForm.ShowProgressText( TheReturnString );
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host %s Connection Failed!' ,
- [ PCRPointer^.CIPAddress ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
- end;
-
- { This is the FTP components USER login routine }
- function TFTPComponent.LoginUser(
- PCRPointer : PConnectionsRecord ) : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- TheReturnString :=
- DoCStyleFormat( 'USER %s' ,
- [ PCRPointer^.CUserName ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Begin login sequence with user name }
- TheResult := PerformFTPCommand( 'USER %s',
- [ PCRPointer^.CUserName ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- FTPCommandInProgress := false;
- Result := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_CONTINUING )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host %s Connection Failed!' ,
- [ PCRPointer^.CIPAddress ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
-
-
- { This is the FTP components PASSWORD routine }
- function TFTPComponent.SendPassword(
- PCRPointer : PConnectionsRecord ) : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- TheReturnString := 'PASS XXXXXX' + #13#10;
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'PASS %s',
- [ PCRPointer^.CPassword ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := false;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host %s Connection Failed!' ,
- [ PCRPointer^.CIPAddress ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
-
- { This is the FTP components CWD routine }
- function TFTPComponent.SetRemoteStartupDirectory(
- PCRPointer : PConnectionsRecord ) : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- Result := true;
- if PCRPointer^.CStartDir <> '' then
- begin
- TheReturnString :=
- DoCStyleFormat( 'CWD %s' ,
- [ PCRPointer^.CStartDir ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'CWD %s',
- [ PCRPointer^.CStartDir ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := false;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'CWD to %s Failed!' ,
- [ PCRPointer^.CStartDir ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
- end;
-
- { This is the FTP components CWD routine }
- function TFTPComponent.SetRemoteDirectory( TheDir : string ) : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- Result := true;
- if TheDir <> '' then
- begin
- TheReturnString :=
- DoCStyleFormat( 'CWD %s' ,
- [ TheDir ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'CWD %s',
- [ TheDir ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := false;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'CWD to %s Failed!' ,
- [ TheDir ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
- end;
-
- { This is the FTP components QUIT routine }
- function TFTPComponent.Disconnect : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- TheReturnString :=
- DoCStyleFormat( 'QUIT' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Begin login sequence with user name }
- TheResult := PerformFTPCommand( 'QUIT',
- [ nil ] );
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host Connection Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else Result := true; { Signal no problem }
- end;
-
- { This is the FTP components PWD routine }
- function TFTPComponent.GetRemoteWorkingDirectory( var RemoteDir : string )
- : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- begin
- Result := true;
- TheReturnString :=
- DoCStyleFormat( 'PWD' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'PWD',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := false;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host Connection Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := False;
- { leave }
- exit;
- end
- else
- begin
- Result := true; { Signal no problem }
- RemoteDir := TheReturnString; { Send back last string on faith }
- end;
- end;
-
- { This function sets up a listening port on socekt 2 and handle text replies }
- function TFTPComponent.GetListeningPort : Integer;
- var
- Address1 ,
- Address2 ,
- Address3 ,
- Address4 : Integer; { Address Integer conversions }
- IPAddress : string; { IP Address holder }
- PortCommand : string; { Command holder }
- TheResult : Integer; { Result holder }
- TheReturnString : string; { ditto }
- begin
- { Set up any port on socket 2 }
- Socket2.PortName := '0';
- { Listen on a socket }
- Socket2.CCSockListen;
- { Get the IP Address of socket 1 and convert it to numbers }
- IPAddress := Socket1.GetSocketIPAddress( Socket1.TheSocket );
- Address1 := StrToInt( copy( IPAddress , 1 , Pos( '.' , IPAddress ) -1 ));
- IPAddress := copy( IPAddress , Pos( '.' , IPAddress ) + 1 , 255 );
- Address2 := StrToInt( copy( IPAddress , 1 , Pos( '.' , IPAddress) -1 ));
- IPAddress := copy( IPAddress , Pos( '.' , IPAddress ) + 1 , 255 );
- Address3 := StrToInt( copy( IPAddress , 1 , Pos( '.' , IPAddress ) -1 ));
- Address4 := StrToInt( copy( IPAddress , Pos( '.' , IPAddress ) + 1 , 255 ));
- { Turn it into a command and add socket 2 stuff }
- PortCommand := format( 'PORT %d,%d,%d,%d,%d,%d' ,
- [ Address1 , Address2 , Address3 , Address4 ,
- StrToInt( Socket2.GetSocketPort( Socket2.TheMasterSocket )) Shr 8,
- StrToInt( Socket2.GetSocketPort( Socket2.TheMasterSocket )) and $ff ]);
- { Put result in progress and status line }
- AddProgressText( PortCommand + #13#10 );
- ShowProgressText( PortCommand + #13#10 );
- TheResult := PerformFTPCommand( PortCommand , [nil] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := FTP_STATUS_FATAL_ERROR;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host Connection Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := TheResult;
- { leave }
- exit;
- end
- else
- begin
- { Return good result and leave }
- Result := TheResult;
- exit;
- end;
- end;
-
- { This function returns part of a unit text string }
- function TFTPComponent.GetUNIXTextString( var StringIn : string ) : string;
- var
- ReturnString : string;
- TheLength ,
- Counter_1 : Integer;
- begin
- TheLength := Length( StringIn );
- if TheLength > 1 then
- begin
- for Counter_1 := 1 to TheLength do
- begin
- if StringIn[ Counter_1 ] = #10 then
- begin
- ReturnString := HolderLine;
- HolderLine := '';
- StringIn := Copy( StringIn , Counter_1 + 1 , 255 );
- Result := ReturnString;
- exit;
- end
- else
- begin
- if StringIn[ Counter_1 ] <> #0 then
- begin
- if StringIn[ Counter_1 ] <> #13 then
- HolderLine := HolderLine + StringIn[ Counter_1 ];
- end
- else
- begin
- Result := '';
- StringIn := '';
- end;
- end;
- end;
- end;
- Result := '';
- StringIn := '';
- end;
-
- procedure TFTPComponent.GetFileNameFromUNIXFileName( var TheName : string );
- var Counter_1 : Integer;
- ResultString : string;
- Finished : Boolean;
- begin
- if Pos( 'TOTAL' , Uppercase( TheName )) <> 0 then
- begin
- TheName := '';
- exit;
- end;
- Counter_1 := Length( TheName );
- ResultString := '';
- Finished := false;
- while not Finished do
- begin
- if TheName[ Counter_1 ] <> ' ' then
- begin
- Counter_1 := Counter_1 - 1;
- if Counter_1 = 0 then
- begin
- ResultString := TheName;
- Finished := true;
- end;
- end
- else
- begin
- Finished := true;
- ResultString := Copy( TheName , Counter_1 + 1 , 255 );
- end;
- end;
- TheName := ResultString;
- end;
-
- { This is the FTP components get remote directory listing into a list box }
- function TFTPComponent.GetRemoteDirectoryListing( TheListBox : TListBox )
- : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- InputString : string;
- Through ,
- Finished : Boolean;
- begin
- TheListBox.Clear;
- TheListBox.Items.Add('..');
- Result := true;
- TheReturnString :=
- DoCStyleFormat( 'TYPE A' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := true;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host Connection Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := true;
- { leave }
- exit;
- end
- else
- begin
- { Set up socket 2 for listening }
- Socket2.AsynchMode := False;
- Socket2.NonAsynchTimeoutValue := 60;
- { do a listen and send command to server that this is receipt socket }
- if GetListeningPort = FTP_STATUS_FATAL_ERROR then
- begin
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket1.NonAsynchTimeoutValue := 0; {infinite timeout}
- TheResult := PerformFTPCommand( 'LIST' , [nil] );
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- Socket1.NonAsynchTimeoutValue := 30;
- if (( TheResult = FTP_STATUS_RETRY_COMMAND ) or
- ( TheResult = FTP_STATUS_FATAL_ERROR )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not obtain remote directory!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Socket2.CCSockCancelListen;
- Result := true;
- exit;
- end;
- Socket2.CCSockAccept;
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not establish receive socket!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Result := true;
- exit;
- end;
- Through := false;
- repeat
- TheReturnString := Socket2.StringData;
- if Length( TheReturnString ) = 0 then Through := true;
- if Length( TheReturnString ) > 0 then
- begin
- finished := false;
- while not finished do
- begin
- InputString := GetUNIXTextString( TheReturnString );
- if InputString = '' then Finished := true else
- begin
- GetFileNameFromUNIXFileName( InputString);
- If InputString <> '' then
- TheListBox.Items.Add( InputString );
- end;
- end;
- end;
- if GlobalAbortedFlag then
- begin
- Socket1.OutOfBand := 'ABOR'+#13#10;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- result := true;
- exit;
- end;
- until Through;
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { cancel listening on second socket and close it }
- Socket2.CCSockCancelListen;
- Socket2.CCSockClose;
- end;
- FTPCommandInProgress := false;
- end;
-
- { This is the FTP components get remote directory listing into a list box }
- function TFTPComponent.GetRemoteDirectoryListingToMemo : Boolean;
- var TheReturnString : string; { Internal string holder }
- TheResult : Integer; { Internal int holder }
- InputString : string;
- Through ,
- Finished : Boolean;
- begin
- Result := true;
- TheReturnString :=
- DoCStyleFormat( 'TYPE A' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { Send Password sequence }
- TheResult := PerformFTPCommand( 'TYPE A',
- [ nil ] );
- if TheResult <> FTP_STATUS_PRELIMINARY then
- begin
- Result := true;
- FTPCommandInProgress := false;
- exit;
- end;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- FTPCommandInProgress := false;
- if ( GlobalAbortedFlag or ( TheResult <> FTP_STATUS_COMPLETED )) then
- begin
- { Do clever C formatting trick }
- TheReturnString :=
- DoCStyleFormat( 'FTP Host Connection Failed!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- { Signal error }
- Result := true;
- { leave }
- exit;
- end
- else
- begin
- { Set up socket 2 for listening }
- Socket2.AsynchMode := False;
- Socket2.NonAsynchTimeoutValue := 30;
- { do a listen and send command to server that this is receipt socket }
- if GetListeningPort = FTP_STATUS_FATAL_ERROR then
- begin
- Socket2.CCSockCancelListen;
- exit;
- end;
- Socket1.NonAsynchTimeoutValue := 0; {infinite timeout}
- TheResult := PerformFTPCommand( 'LIST' , [nil] );
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- Socket1.NonAsynchTimeoutValue := 30;
- if (( TheResult = FTP_STATUS_RETRY_COMMAND ) or
- ( TheResult = FTP_STATUS_FATAL_ERROR )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not obtain remote directory!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Socket2.CCSockCancelListen;
- Result := true;
- exit;
- end;
- Socket2.CCSockAccept;
- if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then
- begin
- TheReturnString :=
- DoCStyleFormat( 'Could not establish receive socket!' ,
- [ nil ] );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressErrorText( TheReturnString );
- Result := true;
- exit;
- end;
- Through := false;
- repeat
- TheReturnString := Socket2.StringData;
- if Length( TheReturnString ) = 0 then Through := true;
- if Length( TheReturnString ) > 0 then
- begin
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- end;
- if GlobalAbortedFlag then
- begin
- Socket1.OutOfBand := 'ABOR'+#13#10;
- repeat
- TheResult := GetFTPServerResponse( TheReturnString );
- { Put result in progress and status line }
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- until (( GlobalAbortedFlag ) or ( TheResult <> FTP_STATUS_PRELIMINARY ));
- result := true;
- exit;
- end;
- until Through;
- GetFTPServerResponse( TheReturnString );
- AddProgressText( TheReturnString );
- ShowProgressText( TheReturnString );
- { cancel listening on second socket and close it }
- Socket2.CCSockCancelListen;
- Socket2.CCSockClose;
- end;
- end;
-
- { This is the FTP components get local directory listing into a list box }
- function TFTPComponent.GetLocalDirectoryAndListing( var TheString : string;
- TheListBox : TListBox )
- : Boolean;
- var TheFLB : TFileListBox;
- begin
- { Get the working directory }
- GetDir( 0 , TheString );
- { Clear incoming LB }
- TheListBox.Clear;
- TheFLB := TFileListBox.Create( Application.MainForm );
- TheFLB.Visible := false;
- TheFLB.Parent := Application.MainForm;
- TheFLB.FileType := [ ftNormal , ftDirectory ];
- TheFLB.Directory := TheString;
- TheFLB.Update;
- TheListBox.Items.Assign( TheFLB.Items );
- TheFLB.Free;
- result := true;
- end;
-
- { This is a clever c-style formatting trick }
- function TFTPComponent.DoCStyleFormat(
- TheText : string;
- const TheArguments : array of const ) : string;
- begin
- Result := Format( TheText , TheArguments ) + #13#10;
- end;
-
- function TFTPComponent.GetQuotedString( TheString : string ) : string;
- var TheIndex : Integer; { Holder var }
- ResultString : string; { ditto }
- begin
- { Find out if " present at all }
- TheIndex := Pos( '"' , TheString );
- If TheIndex = 0 then
- begin
- { If not, return null string and exit }
- Result := '';
- exit;
- end
- else
- begin
- { Get from first " to end of string in holder }
- ResultString := Copy( TheString , TheIndex + 1 , 255 );
- { Find position to second " }
- TheIndex := Pos( '"' , ResultString );
- { If no ending " then return whole string and leave }
- if TheIndex = 0 then
- begin
- Result := ResultString;
- exit;
- end
- else
- begin
- { Get internal text between quotes and exit }
- ResultString := Copy( ResultString , 1 , TheIndex - 1 );
- Result := ResultString;
- end;
- end;
- end;
-
- procedure TCCINetCCForm.UpdateGauge( BytesFinished , TotalToHandle : longint );
- var
- Percentage : longint;
- begin
- if BytesFinished > TotalToHandle then BytesFinished := TotalToHandle;
- if TotalToHandle = 0 then exit;
- Percentage := Trunc( 100.0 / ( TotalToHandle / BytesFinished ));
- Gauge1.Progress := Percentage;
- Panel1.Caption := ' Status: Transfered ' + IntToStr( BytesFinished ) +
- ' bytes of file ' + FileNameToXFer + ' (' + IntToStr( Percentage ) + '% Complete)';
- end;
-
- { This procedure actually attempts to connect to the internet at an ftp site }
- function TCCINetCCForm.DoFTPConnection( PCRPointer : PConnectionsRecord ) : boolean;
- var TheReturnString : string; { Display results of connection in status lines }
- TheResult : Integer;{ Result from FTP server }
- FTPLoggedIn : Boolean;{ Boolean to signal successful login }
- begin
- { Create the component }
- Result := false;
- { Do busy cursors }
- SetHGCursors;
- if not TheFTPComponent.EstablishConnection( PCRPointer ) then
- begin
- { Do saved cursors }
- TheFTPComponent.FTPCommandInProgress := false;
- TheFTPComponent.Connection_Established := false;
- SetNormalCursors;
- exit;
- end
- else
- begin { Connected; continue login process }
- if not TheFTPComponent.LoginUser( PCRPointer ) then
- begin
- { Do saved cursors }
- TheFTPComponent.FTPCommandInProgress := false;
- TheFTPComponent.Connection_Established := false;
- SetNormalCursors;
- exit;
- end;
- if not TheFTPComponent.SendPassword( PCRPointer ) then
- begin
- { Do saved cursors }
- TheFTPComponent.FTPCommandInProgress := false;
- TheFTPComponent.Connection_Established := false;
- SetNormalCursors;
- exit;
- end;
- if not TheFTPComponent.SetRemoteStartupDirectory( PCRPointer ) then
- begin
- { Do saved cursors }
- SetNormalCursors;
- TheFTPComponent.Connection_Established := false;
- TheFTPComponent.FTPCommandInProgress := false;
- exit;
- end;
- if not TheFTPComponent.GetRemoteWorkingDirectory( TheReturnString ) then
- begin
- { Do saved cursors }
- TheFTPComponent.Connection_Established := false;
- TheFTPComponent.FTPCommandInProgress := false;
- SetNormalCursors;
- exit;
- end;
- { Put up remote directory via PWD and strip quotes }
- Label4.Caption := TheFTPComponent.GetQuotedString( TheReturnString );
- { Get the listings of directories and exit OK }
- TheFTPComponent.GetRemoteDirectoryListing( Listbox1 );
- TheFTPComponent.GetLocalDirectoryAndListing( TheReturnString ,
- Listbox2 );
- if Label5.Canvas.TextWidth( TheReturnString ) > Label5.Width then
- TheReturnString := TheFTPComponent.GetShortPathName( TheReturnString );
- Label5.Caption := TheReturnString;
- SetNormalCursors;
- Result := true;
- EnableFTPMenus;
- TheFTPComponent.FTPCommandInProgress := false;
- Panel1.Caption := ' Status : Connected to ' + PCRPointer^.CIPAddress;
- end;
- end;
-
- { This procedure actually attempts to disconnect to the internet at an ftp site}
- procedure TCCINetCCForm.DoFTPDisconnect;
- begin
- { Call QUIT command }
- TheFTPComponent.Disconnect;
- { Kill the socket }
- TheFTPComponent.Socket1.CCSockClose;
- end;
-
- { This procedure reads in the ini file and default path info }
- procedure TCCINetCCForm.ReadIniData;
- begin
- TheICCIniFile := TIniFile.Create( 'CCICC.INI' );
- MailPath := TheICCIniFile.ReadString( 'Paths','MailPath','C:\WINDOWS' );
- NewsPath := TheICCIniFile.ReadString( 'Paths','NewsPath','C:\WINDOWS' );
- WWWPath := TheICCIniFile.ReadString( 'Paths','WWWPath','C:\WINDOWS' );
- FTPPath := TheICCIniFile.ReadString( 'Paths','FTPPath','C:\WINDOWS' );
- PasswordControlVector := TheICCIniFile.ReadInteger( 'Vectors','PWControl',2 );
- DefaultDownloadVector := TheICCIniFile.ReadInteger( 'Vectors','DefDL', 3 );
- TheAnonRedialVector := TheICCIniFile.ReadInteger( 'Vectors','AnonRD', 20 );
- TheICCIniFile.Free;
- end;
-
- { This procedure writes out default path data to the ini file }
- procedure TCCINetCCForm.WriteIniData;
- begin
- TheICCIniFile := TIniFile.Create( 'CCICC.INI' );
- TheICCIniFile.WriteString( 'Paths','MailPath',MailPath );
- TheICCIniFile.WriteString( 'Paths','NewsPath',NewsPath );
- TheICCIniFile.WriteString( 'Paths','WWWPath',WWWPath );
- TheICCIniFile.WriteString( 'Paths','FTPPath',FTPPath );
- TheICCIniFile.WriteInteger( 'Vectors','PWControl',PasswordControlVector );
- TheICCIniFile.WriteInteger( 'Vectors','DefDL',DefaultDownloadVector );
- TheICCIniFile.WriteInteger( 'Vectors','AnonRD', TheAnonRedialVector );
- TheICCIniFile.Free;
- end;
-
- { Procedure to load the FTP Site list }
- procedure TCCINetCCForm.LoadFTPSiteFile;
- var TheTCRecord : PConnectionsRecord; { Generic TCR Pointer }
- FTPSLName : string; { FTP Site List filename }
- Counter_1 : Integer; { Loop counter }
- begin
- { Create the sites list list }
- TheFTPSiteList := TList.Create;
- { Set up the FTP sites list file name }
- FTPSLName := FTPPath + '\FTPSITES.TCR';
- { If the FTP Site List exists load it in }
- if FileExists( FTPSLName ) then
- begin
- { set up the file and open it }
- AssignFile( TheFTPSiteFile , FTPSLName );
- Reset( TheFTPSiteFile );
- { read in the records }
- for Counter_1 := 0 to FileSize( TheFTPSiteFile ) - 1 do
- begin
- { Create the TCRecord }
- New( TheTCRecord );
- { Read in the data record }
- Seek( TheFTPSiteFile , Counter_1 );
- Read( TheFTPSiteFile , TheTCRecord^ );
- { Add the record to the list }
- TheFTPSiteList.Add( TheTCRecord );
- end;
- { close the file }
- CloseFile( TheFTPSiteFile );
- end
- else
- { Otherwise create a default one with a few anonymous sites }
- begin
- { create new record }
- New( TheTCRecord );
- { fill in its info }
- with TheTCRecord^ do
- begin
- CProfile := 'Winsite Windows Archive';
- CIPAddress := 'ftp.winsite.com';
- CUserName := 'anonymous';
- CPassword := 'guest@nowhere.com';
- CStartDir := '';
- end;
- { add it to the list }
- { do it three more times }
- TheFTPSiteList.Add( TheTCRecord );
- New( TheTCRecord );
- with TheTCRecord^ do
- begin
- CProfile := 'Digital Equipment Corp';
- CIPAddress := 'gatekeeper.dec.com';
- CUserName := 'anonymous';
- CPassword := 'guest@nowhere.com';
- CStartDir := '';
- end;
- TheFTPSiteList.Add( TheTCRecord );
- New( TheTCRecord );
- with TheTCRecord^ do
- begin
- CProfile := 'Microsoft FTP Site';
- CIPAddress := 'ftp.microsoft.com';
- CUserName := 'anonymous';
- CPassword := 'guest@nowhere.com';
- CStartDir := '';
- end;
- TheFTPSiteList.Add( TheTCRecord );
- New( TheTCRecord );
- with TheTCRecord^ do
- begin
- CProfile := 'Oakland MSDOS Archive';
- CIPAddress := 'oak.oakland.edu';
- CUserName := 'anonymous';
- CPassword := 'guest@nowhere.com';
- CStartDir := '';
- end;
- TheFTPSiteList.Add( TheTCRecord );
- { create the file and write out the data, then close it }
- AssignFile( TheFTPSiteFile , FTPSLName );
- Rewrite( TheFTPSiteFile );
- for Counter_1 := 0 to 3 do
- begin
- TheTCRecord :=
- PConnectionsRecord( TheFTPSiteList.Items[ Counter_1 ] );
- Seek( TheFTPSiteFile , Counter_1 );
- Write( TheFTPSiteFile , TheTCRecord^ );
- end;
- CloseFile( TheFTPSiteFile );
- end;
- end;
-
- { This procedure saves off the FTP Site List }
- procedure TCCINetCCForm.SaveFTPSiteFile;
- var TheTCRecord : PConnectionsRecord; { The TC Record pointer }
- FTPSLName : string; { FTP Site List filename }
- Counter_1 : Integer; { Loop counter }
- begin
- { Set up the file name }
- FTPSLName := FTPPath + '\FTPSITES.TCR';
- { Assign the file }
- AssignFile( TheFTPSiteFile , FTPSLName );
- { Rewrite it }
- Rewrite( TheFTPSiteFile );
- { run the list through the procedure }
- for Counter_1 := 0 to TheFTPSiteList.Count - 1 do
- begin
- { get the record from the list }
- TheTCRecord :=
- PConnectionsRecord( TheFTPSiteList.Items[ Counter_1 ] );
- { Do the seek/write }
- Seek( TheFTPSiteFile , Counter_1 );
- Write( TheFTPSiteFile , TheTCRecord^ );
- { free the record }
- Dispose( TheTCRecord );
- end;
- { Close the file }
- CloseFile( TheFTPSiteFile );
- { Free the list pointers }
- TheFTPSiteList.Free;
- TheWorkingFTPSL.Free;
- end;
-
- { This procedure switches in the FTP sites list to the info dlg and main cbox }
- procedure TCCINetCCForm.SetupFTPSiteLists;
- var ThePointer : PConnectionsRecord; { Generic PCR Pointer }
- Counter_1 : Integer; { Loop counter }
- begin
- { Set up display for main form }
- CCINetCCForm.Tag := 2;
- CCINetCCForm.Caption := 'CC Internet Command Center -- FTP Mode';
- CCINetCCForm.ViewWinsockInfo1.Enabled := false;
- CCINetCCForm.FTP1.Enabled := false;
- CCINetCCForm.FTP2.Enabled := true;
- CCINetCCForm.Label1.Caption := 'FTP Site:';
- CCINetCCForm.Button1.Caption := 'Connect';
- CCINetCCForm.Label4.Caption := 'Local Dir';
- CCINetCCForm.Label5.Caption := 'Remote Dir';
- { Set tag for FTP stuff }
- CCICInfoDlg.Tag := 2;
- { set up caption of main label }
- CCICInfoDlg.Label2.Caption := 'FTP Sites';
- { hide outline panel }
- CCICInfoDlg.Panel6.Visible := false;
- { clear the list box }
- CCICInfoDlg.ListBox2.Clear;
- CCINetCCForm.ComboBox1.Clear;
- { add profile strings to the list box }
- for Counter_1 := 0 to TheFTPSiteList.Count - 1 do
- begin
- CCICInfoDlg.ListBox2.Items.Add( PConnectionsRecord(
- TheFTPSiteList.Items[ Counter_1 ] )^.CProfile );
- CCINetCCForm.ComboBox1.Items.Add( PConnectionsRecord(
- TheFTPSiteList.Items[ Counter_1 ] )^.CProfile );
- end;
- { Set up caption of special button }
- CCICInfoDlg.Button1.Caption := 'Anonymous Login';
- { Start with top record }
- CCICInfoDlg.ListBox2.ItemIndex := 0;
- CCINetCCForm.ComboBox1.ItemIndex := 0;
- { put in data from top record and reset captions }
- with PConnectionsRecord( TheFTPSiteList.Items[ 0 ] )^ do
- begin
- with CCICInfoDlg do
- begin
- Edit1.Text := CProfile;
- Panel2.Caption := ' Name:';
- Edit2.Text := CIPAddress;
- Panel3.Caption := ' IP Address:';
- Edit3.Text := CUserName;
- Panel5.Caption := ' User Name:';
- case PasswordControlVector of
- 1 : Edit4.Text := CPassword;
- 2 : Edit4.Text := '**********';
- end;
- Panel8.Caption := ' Password:';
- Edit5.Text := CStartDir;
- Panel9.Caption := ' Starting Dir:';
- end;
- end;
- { Create the working copy for use to make safe changes in info dlg }
- TheWorkingFTPSL := TList.Create;
- For Counter_1 := 0 to TheFTPSiteList.Count - 1 do
- begin
- New( ThePointer );
- ThePointer^ := PConnectionsRecord( TheFTPSiteList.Items[ Counter_1 ] )^;
- TheWorkingFTPSL.Add( ThePointer );
- end;
- end;
-
- { This procedure scans a line of UNIX-style text for #10's and }
- { outputs them as lines to the memo. It stops at #0. }
- procedure TCCINetCCForm.AddNullTermTextToMemo( TheTextToAdd : string;
- TheMemoToAddTo : TMemo );
- var
- TextLength , { Total chars to output }
- Counter_1 : Integer; { Loop Index }
- begin
- { Make the target memo visible just in case }
- TheMemoToAddTo.Visible := true;
- { Find total chars to output }
- TextLength := Length( TheTextToAdd );
- { If none then leave }
- if TextLength = 0 then exit;
- { Loop along the string }
- for Counter_1 := 1 to TextLength do
- begin
- { If hit ASCII 10 then assume end of line and output }
- if TheTextToAdd[ Counter_1 ] = #10 then
- begin
- { Use a try loop incase memo fills up }
- try
- { Add the line }
- TheMemoToAddTo.Lines.Add( TheLine );
- except
- { If memo fills up }
- on EOutOfResources do
- begin
- { Clear the old data }
- TheMemoToAddTo.Clear;
- { Output the new }
- TheMemoToAddTo.Lines.Add( TheLine );
- end;
- end;
- { clear the output buffer }
- TheLine := '';
- end
- else
- { Otherwise look for null terminator from Winsock }
- begin
- { If don't hit null terminator then add the char to op buffer }
- if TheTextToAdd[ Counter_1 ] <> #0 then
- begin
- TheLine := TheLine + TheTextToAdd[ Counter_1 ];
- end
- else
- begin
- if TheLine <> '' then
- begin
- { Use a try loop incase memo fills up }
- try
- { Add the line }
- TheMemoToAddTo.Lines.Add( TheLine );
- except
- { If memo fills up }
- on EOutOfResources do
- begin
- { Clear the old data }
- TheMemoToAddTo.Clear;
- { Output the new }
- TheMemoToAddTo.Lines.Add( TheLine );
- end;
- end;
- { clear the output buffer }
- TheLine := '';
- end;
- end;
- end;
- end;
- end;
-
- { This function scans a line of UNIX-style text for #10's and }
- { outputs the first line as its return value,stopping at #0. }
- function TCCINetCCForm.AddNullTermTextToLabel( TheTextToAdd : string ) : string;
- var
- TheLine : string; { Buffer to output current line }
- TextLength , { Total chars to output }
- Counter_1 : Integer; { Loop Index }
- begin
- { Clear output buffer }
- TheLine := '';
- { Find total chars to output }
- TextLength := Length( TheTextToAdd );
- { If none then leave }
- if TextLength = 0 then
- begin
- { Return nothing }
- Result := '';
- { Leave }
- exit;
- end;
- { Loop along the string }
- for Counter_1 := 1 to TextLength do
- begin
- { If hit ASCII 10 then assume end of line and output }
- if TheTextToAdd[ Counter_1 ] = #10 then
- begin
- { Return first line }
- Result := TheLine;
- { Leave }
- exit;
- end
- else
- { Otherwise look for null terminator from Winsock }
- begin
- { If don't hit null terminator then add the char to op buffer }
- if TheTextToAdd[ Counter_1 ] <> #0 then
- begin
- TheLine := TheLine + TheTextToAdd[ Counter_1 ];
- end
- else break; { Otherwise drop out of the loop }
- end;
- end;
- { If hit #0 before #10 return buffer }
- Result := TheLine;
- end;
-
- { Show busy cursors }
- procedure TCCINetCCForm.SetHGCursors;
- begin
- CCInetCCForm.Cursor := crHourGlass;
- CCInetCCForm.Memo1.Cursor := crHourGlass;
- end;
-
- { Show normal cursors }
- procedure TCCINetCCForm.SetNormalCursors;
- begin
- CCInetCCForm.Cursor := crDefault;
- CCInetCCForm.Memo1.Cursor := crDefault;
- end;
-
- { Exit method }
- procedure TCCINetCCForm.Exit1Click(Sender: TObject);
- begin
- Close;
- end;
-
- { This method adds a line to the progress text stringlist }
- { If an exception occurs, the list is full, and it is auto }
- { saved to the progress text file name, then cleared. }
- procedure TCCINetCCForm.AddProgressText( WhatText : string );
- begin
- { Use a try..except loop to catch list overflows }
- try
- { Try the normal add }
- ProgressList.Add( WhatText );
- except
- { Any list error is assumed to be a list overflow }
- on EListError do
- begin
- { Save the list to the preset file name }
- ProgressList.SaveToFile( ProgressFileName );
- { Clear the list to make more room }
- ProgressList.Clear;
- { And redo the add; any further errors will except normally }
- ProgressList.Add( WhatText );
- end;
- { This might happen too! }
- on EOutOfResources do
- begin
- { Save the list to the preset file name }
- ProgressList.SaveToFile( ProgressFileName );
- { Clear the list to make more room }
- ProgressList.Clear;
- { And redo the add; any further errors will except normally }
- ProgressList.Add( WhatText );
- end;
- end;
- end;
-
- { This method either adds the progress line to the current memo }
- { or puts it in the status caption at normal colors. }
- procedure TCCINetCCForm.ShowProgressText( WhatText : string );
- begin
- { Use the POV to determine where to show progress info }
- case ProgressOutputVector of
- POV_MEMO : begin { Output into the memo }
- AddNullTermTextToMemo( WhatText , Memo1 );
- end;
- POV_STAT : begin { Output on status line }
- { Set panel caption font to black }
- Panel1.Font.Color := clBlack;
- { Get the first line of text and put in caption }
- Panel1.Caption := AddNullTermTextToLabel( WhatText );
- end;
- end;
- end;
-
- { This method is identical with SPT except sets status color to red and beeps }
- procedure TCCINetCCForm.ShowProgressErrorText( WhatText : string );
- begin
- { Do error beep }
- MessageBeep( mb_IconExclamation );
- { Use the POV to determine where to show progress info }
- case ProgressOutputVector of
- POV_MEMO : begin { Output into the memo }
- AddNullTermTextToMemo( WhatText , Memo1 );
- end;
- POV_STAT : begin { Output on status line }
- { Set panel caption font to black }
- Panel1.Font.Color := clRed;
- { Get the first line of text and put in caption }
- Panel1.Caption := AddNullTermTextToLabel( WhatText );
- end;
- end;
- end;
-
- { This is the boilerplate method used to handle Socket errors gracefully }
- procedure TCCINetCCForm.SocketsErrorOccurred( Sender : TObject;
- ErrorCode : Integer;
- TheMessage : string );
- begin
- { Set the global error code flag }
- GlobalErrorCode := ErrorCode;
- { If a timeout error }
- if ErrorCode = WSAETIMEDOUT then
- begin
- { Set the aborted flag }
- GlobalAbortedFlag := True;
- { But clear the error code for graceful handling }
- GlobalErrorCode := 0;
- end
- else
- begin
- { Otherwise set the progress buffer to the error message }
- AddProgressText( TheMessage );
- { And show the progress text as set by option }
- ShowProgressErrorText( TheMessage );
- end;
- end;
-
- procedure TCCINetCCForm.FormCreate(Sender: TObject);
- begin
- { Create the progress string list }
- ProgressList := TStringList.Create;
- { Create the file name for saving the progress list }
- ProgressFileName := ExpandFileName( 'PROGRESS.TXT' );
- { Default progress output to status line }
- ProgressOutputVector := POV_STAT;
- { Set password control stuff }
- PasswordControlVector := 2;
- CurrentPasswordString := 'guest@nowhere.com';
- CurrentRealPWString := 'guest@nowhere.com';
- { Get Ini file Data }
- ReadIniData;
- LoadFTPSiteFile;
- end;
-
- procedure TCCINetCCForm.FormDestroy(Sender: TObject);
- begin
- { Free the progress text stringlist if assigned }
- if assigned( ProgressList ) then ProgressList.Free;
- { Save off the Ini data }
- WriteIniData;
- { Save and remove FTP site list stuff }
- SaveFTPSiteFile;
- if Assigned( TheFTPComponent ) then TheFTPComponent.Free;
- end;
-
- procedure TCCINetCCForm.Description1Click(Sender: TObject);
- var
- TempSocket : TCCSocket; { Temporary socket just to get Winsock info }
- TheData : string; { Holder for data }
- begin
- { Create socket; auto calls WSAStartup }
- TempSocket := TCCSocket.Create( Self );
- { Do parent just for kicks; no longer needed }
- TempSocket.Parent := self;
- { Put in error handler }
- TempSocket.OnErrorOccurred := SocketsErrorOccurred;
- TheData := StrPas( TempSocket.Socket_WSA_Data.Description_String );
- { Display the Description string }
- AddProgressText( TheData + #0 );
- { And show the progress text as set by option }
- ShowProgressText( TheData + #0 );
- { Free the socket; auto calls WSACleanup }
- TempSocket.Free;
- end;
-
- procedure TCCINetCCForm.SystemStatus1Click(Sender: TObject);
- var
- TempSocket : TCCSocket; { Temporary socket just to get Winsock info }
- TheData : string; { Holder for data }
- begin
- { Create socket; auto calls WSAStartup }
- TempSocket := TCCSocket.Create( Self );
- { Do parent just for kicks; no longer needed }
- TempSocket.Parent := self;
- { Put in error handler }
- TempSocket.OnErrorOccurred := SocketsErrorOccurred;
- TheData := StrPas( TempSocket.Socket_WSA_Data.System_Status_String );
- { Display the Description string }
- AddProgressText( TheData + #0 );
- { And show the progress text as set by option }
- ShowProgressText( TheData + #0 );
- { Free the socket; auto calls WSACleanup }
- TempSocket.Free;
- end;
-
- procedure TCCINetCCForm.VendorSpecific1Click(Sender: TObject);
- var
- TempSocket : TCCSocket; { Temporary socket just to get Winsock info }
- TheData : string; { Holder for data }
- begin
- { Create socket; auto calls WSAStartup }
- TempSocket := TCCSocket.Create( Self );
- { Do parent just for kicks; no longer needed }
- TempSocket.Parent := self;
- { Put in error handler }
- TempSocket.OnErrorOccurred := SocketsErrorOccurred;
- TheData := StrPas( TempSocket.Socket_WSA_Data.Vendor_Specific_String );
- { Display the Description string }
- AddProgressText( TheData + #0 );
- { And show the progress text as set by option }
- ShowProgressText( TheData + #0 );
- { Free the socket; auto calls WSACleanup }
- TempSocket.Free;
- end;
-
- { This method sets the progress output vector to the memo }
- procedure TCCINetCCForm.ViewInEditWindow1Click(Sender: TObject);
- begin
- { Set the vector }
- ProgressOutputVector := POV_MEMO;
- { Keep the menu options consistent }
- ViewInEditWindow1.Checked := true;
- ViewInStatusLine1.Checked := false;
- end;
-
- { This method sets the progress output vector to the status line }
- procedure TCCINetCCForm.ViewInStatusLine1Click(Sender: TObject);
- begin
- { Set the vector }
- ProgressOutputVector := POV_STAT;
- { Keep the menus consistent }
- ViewInEditWindow1.Checked := false;
- ViewInStatusLine1.Checked := true;
- end;
-
- procedure TCCINetCCForm.SaveToFile1Click(Sender: TObject);
- begin
- { Set up the dialog parameters }
- OpenDialog1.Filename := ProgressFileName;
- OpenDialog1.Title := 'Select Filename for Progress File';
- OpenDialog1.Filter := 'Text Files|*.txt';
- { If the dialog is not cancelled then save and clear }
- if OpenDialog1.Execute then
- begin
- ProgressFileName := OpenDialog1.FileName;
- ProgressList.SaveToFile( ProgressFileName );
- ProgressList.Clear;
- end;
- end;
-
- procedure TCCINetCCForm.IPAddress1Click(Sender: TObject);
- begin
- { Set up info dialog for IP Address getting }
- CCICInfoDlg.Caption := 'CC Internet Center -- Translate IP Address';
- CCICInfoDlg.Panel4.Visible := false;
- CCICInfoDlg.Panel6.Visible := false;
- CCICInfoDlg.Panel9.Visible := false;
- CCICInfoDlg.Panel8.Visible := false;
- CCICInfoDlg.BitBtn2.Visible := false;
- CCICInfoDlg.Button1.Caption := 'Get IP Address';
- CCICInfoDlg.Button2.Visible := false;
- CCICInfoDlg.Button3.Visible := false;
- CCICInfoDlg.Button4.Visible := false;
- CCICInfoDlg.Panel2.Caption := 'IP Addr Name:';
- CCICInfoDlg.Panel3.Caption := ' Dotted Dec:';
- CCICInfoDlg.Panel5.Caption := ' Binary:';
- CCICInfoDlg.Edit1.Text := '';
- CCICInfoDlg.Edit2.Text := '';
- CCICInfoDlg.Edit3.Text := '';
- { Set IP Address Mode }
- CCICInfoDlg.Tag := 1;
- { Show Modally to get the information }
- CCICInfoDlg.ShowModal;
- { Reset the info dialog to default conditions }
- CCICInfoDlg.Caption := 'CC Internet Command Center Information Dialog';
- CCICInfoDlg.Panel4.Visible := true;
- CCICInfoDlg.Panel6.Visible := true;
- CCICInfoDlg.Panel9.Visible := true;
- CCICInfoDlg.Panel8.Visible := true;
- CCICInfoDlg.BitBtn2.Visible := true;
- CCICInfoDlg.Button1.Caption := 'Anonymous Login';
- CCICInfoDlg.Button2.Visible := true;
- CCICInfoDlg.Button3.Visible := true;
- CCICInfoDlg.Button4.Visible := true;
- CCICInfoDlg.Panel2.Caption := ' Name:';
- CCICInfoDlg.Panel3.Caption := ' IP Address:';
- CCICInfoDlg.Panel5.Caption := ' User Name:';
- CCICInfoDlg.Edit1.Text := '';
- CCICInfoDlg.Edit2.Text := '';
- CCICInfoDlg.Edit3.Text := '';
- end;
-
- procedure TCCINetCCForm.FTP1Click(Sender: TObject);
- begin
- { Set up the FTP Data displays }
- SetupFTPSiteLists;
- TheFTPComponent := TFTPComponent.Create( CCInetCCForm );
- TheFTPComponent.Parent := CCInetCCForm;
- end;
-
- procedure TCCINetCCForm.FormResize(Sender: TObject);
- begin
- { Use tag vector to determine what to do }
- case Tag of
- { if FTP , make sure two list boxes are same height }
- 2 : Panel6.Height := (( Panel4.Height div 2 ) - 30 );
- end;
- end;
-
- procedure TCCINetCCForm.FTPSites1Click(Sender: TObject);
- begin
- { Show Modally to get the information }
- CCICInfoDlg.ShowModal;
- end;
-
- procedure TCCINetCCForm.FTP3Click(Sender: TObject);
- begin
- CCICPrefsDlg.TabbedNoteBook1.PageIndex := 1;
- CCICPrefsDlg.Tag := 2;
- CCICPrefsDlg.ShowModal;
- end;
-
- procedure TCCINetCCForm.ConnectToSite1Click(Sender: TObject);
- var Counter_1 : Integer;
- begin
- if Lowercase( PConnectionsRecord( TheFTPSiteList.Items[
- ComboBox1.ItemIndex ] )^.CUserName ) = 'anonymous' then
- begin
- for Counter_1 := 1 to TheAnonRedialVector do
- begin
- DoFTPConnection( PConnectionsRecord(
- TheFTPSiteList.Items[ ComboBox1.ItemIndex ] ));
- if TheFTPComponent.Connection_Established then exit;
- end;
- end
- else DoFTPConnection( PConnectionsRecord(
- TheFTPSiteList.Items[ ComboBox1.ItemIndex ] ));
- end;
-
- procedure TCCINetCCForm.Button1Click(Sender: TObject);
- begin
- case Tag of
- 2 : begin
- if not TheFTPComponent.Connection_Established then
- ConnectToSite1Click( Self ) else
- begin
- DoFTPDisconnect;
- TheFTPComponent.Connection_Established := false;
- DisableFTPMenus;
- end;
- end;
- end;
- end;
-
- procedure TCCINetCCForm.ViewasText1Click(Sender: TObject);
- begin
- { Assume valid FTP component and have it send its text into the progress text}
- TheFTPComponent.GetRemoteDirectoryListingToMemo;
- end;
-
- procedure TCCINetCCForm.Disconnect1Click(Sender: TObject);
- begin
- DoFTPDisconnect;
- DisableFTPMenus;
- end;
-
- procedure TCCINetCCForm.EnableFTPMenus;
- begin
- Button1.Caption := 'Disconnect';
- ConnectToSite1.Enabled := false;
- Disconnect1.Enabled := true;
- Directory1.Enabled := true;
- UploadMarked1.Enabled := true;
- DownloadMarked1.Enabled := true;
- end;
-
- procedure TCCINetCCForm.DisableFTPMenus;
- begin
- Button1.Caption := 'Connect';
- ConnectToSite1.Enabled := true;
- Disconnect1.Enabled := false;
- Directory1.Enabled := false;
- UploadMarked1.Enabled := false;
- DownloadMarked1.Enabled := false;
- end;
-
- procedure TCCINetCCForm.ToDisplay1Click(Sender: TObject);
- var Counter_1 : Integer;
- begin
- for Counter_1 := 0 to Listbox1.Items.Count - 1 do
- begin
- if Listbox1.Selected[ Counter_1 ] then
- begin
- FileNameToXFer := ListBox1.Items[ Counter_1 ];
- TheFTPComponent.
- ReceiveASCIIRemoteFileToMemo( Listbox1.Items[ Counter_1 ] );
- end;
- end;
- end;
-
- procedure TCCINetCCForm.ToFile1Click(Sender: TObject);
- var Counter_1 : Integer;
- W16Name : string;
- begin
- for Counter_1 := 0 to Listbox1.Items.Count - 1 do
- begin
- if Listbox1.Selected[ Counter_1 ] then
- begin
- FileNameToXFer := ListBox1.Items[ Counter_1 ];
- W16Name := TheFTPComponent.GetWin16Filename( FileNameToXFer );
- TheFTPComponent.
- ReceiveASCIIRemoteFile( Listbox1.Items[ Counter_1 ] , W16Name );
- end;
- end;
- end;
-
- procedure TCCINetCCForm.Change1Click(Sender: TObject);
- var TheDir : string;
- begin
- if ListBox1.ItemIndex = -1 then exit;
- TheDir := ListBox1.Items[ ListBox1.ItemIndex ];
- if TheFTPComponent.SetRemoteDirectory( TheDir ) then
- begin
- TheFTPComponent.GetRemoteWorkingDirectory( TheDir );
- { Put up remote directory via PWD and strip quotes }
- Label4.Caption := TheFTPComponent.GetQuotedString( TheDir );
- { Get the listings of directories and exit OK }
- TheFTPComponent.GetRemoteDirectoryListing( Listbox1 );
- end;
- end;
-
- procedure TCCINetCCForm.ChangeLocal1Click(Sender: TObject);
- var TheDir : string;
- begin
- if ListBox2.ItemIndex = -1 then exit;
- TheDir := ListBox2.Items[ ListBox2.ItemIndex ];
- TheDir := TheFTPComponent.StripBrackets( TheDir );
- if TheDir = '..' then
- begin
- ChDir( TheDir );
- end
- else
- begin
- TheDir := ExpandFileName( TheDir );
- ChDir( TheDir );
- end;
- TheFTPComponent.GetLocalDirectoryAndListing( TheDir , Listbox2 );
- if Label5.Canvas.TextWidth( TheDir ) > Label5.Width then
- TheDir := TheFTPComponent.GetShortPathName( TheDir );
- Label5.Caption := TheDir;
- end;
-
- procedure TCCINetCCForm.ListBox1DblClick(Sender: TObject);
- begin
- case Tag of
- 2 : begin
- case DefaultDownLoadVector of
- 3 : Change1Click( Self );
- end;
- end;
- end;
- end;
-
- procedure TCCINetCCForm.ListBox2DblClick(Sender: TObject);
- begin
- case Tag of
- 2 : begin
- case DefaultDownLoadVector of
- 3 : ChangeLocal1Click( Self );
- end;
- end;
- end;
- end;
-
- end.
-