?
Solved

Create FTP Server

Posted on 2004-11-29
11
Medium Priority
?
639 Views
Last Modified: 2010-04-05
hi, how would I go about creating a FTP Server, using the idFTPServer1 from indy.

has to be able to list the selected directory, and move/delete/edit, upload/download.

if you have any code snipets and links please post them below.

I will give more points when posting working code than to post links, posting links with code will give u both.
0
Comment
Question by:SaLz
10 Comments
 

Assisted Solution

by:jonas78
jonas78 earned 400 total points
ID: 12700713
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 12700952
Hi,

I'm having problems in providing source, because Indy FTP server gives me a
problem. Will get back asap when I'll be understanding what goes wrong.

Cheers,

Andrew
0
 
LVL 2

Author Comment

by:SaLz
ID: 12701110
jonas78, the links you provided are far from a ftp server, the 1+4 links are for clients and use NMFTP1, 2+3 have no useful information about creating a ftp server, but its a start, do you know any other links or know of components for ftp other than indy and the links associated with them.

with indy ftp server, I can connect to the ftp server, but when the client ask for the listing directory, am stumped.

the ftp server isn't well documented, and having trouble finding information on the means of creating a ftp server.

any code/links about 'ftp server' would be much appreciated.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 5

Accepted Solution

by:
DeerBear earned 1200 total points
ID: 12701268
Ok, this code should get you started.

Please consider that there're bugs, so you'll need to fix it, since I wrote it "flying" few minutes ago.
But should be nuff for a kickstart.

Enjoy!!!!

unit MainCode;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient, StdCtrls, IdBaseComponent, IdComponent,
  IdTCPServer, IdFTPServer, idFTPList;

type
  TMainFrm = class(TForm)
    GroupBox1: TGroupBox;
    FolderRootEdit: TEdit;
    StartBtn: TButton;
    StopBtn: TButton;
    FTPSrv: TIdFTPServer;
    GroupBox2: TGroupBox;
    LogMemo: TMemo;
    procedure StartBtnClick(Sender: TObject);
    procedure StopBtnClick(Sender: TObject);
    procedure FTPSrvListDirectory(ASender: TIdFTPServerThread;
      const APath: String; ADirectoryListing: TIdFTPListItems);
    procedure FTPSrvGetFileSize(ASender: TIdFTPServerThread;
      const AFilename: String; var VFileSize: Int64);
    procedure FTPSrvConnect(AThread: TIdPeerThread);
    procedure FTPSrvStoreFile(ASender: TIdFTPServerThread;
      const AFileName: String; AAppend: Boolean; var VStream: TStream);
    procedure FTPSrvRetrieveFile(ASender: TIdFTPServerThread;
      const AFileName: String; var VStream: TStream);
    procedure FTPSrvDeleteFile(ASender: TIdFTPServerThread;
      const APathName: String);
  private
    function GetBaseDir: String;
    { Private declarations }
  public
    { Public declarations }
    property BaseDir : String read GetBaseDir;
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.dfm}

function TMainFrm.GetBaseDir: String;
begin
  if FolderRootEdit.Text = '' then
  begin
    Result := ExtractFilePath( ParamStr( 0 ) )+'pub';
  end;
end;

procedure TMainFrm.StartBtnClick(Sender: TObject);
begin
  FTPSrv.Active := True;
  ChDir( BaseDir );
end;

procedure TMainFrm.StopBtnClick(Sender: TObject);
begin
  FTPSrv.Active := False;
end;

procedure TMainFrm.FTPSrvListDirectory(ASender: TIdFTPServerThread;
  const APath: String; ADirectoryListing: TIdFTPListItems);
var SR : TSearchRec;
    FTPLI : TidFTPListItem;
begin
//  GetFolderList( APath, FileNames );
(*  ADirectoryListing.LoadList( FileNames );
  ADirectoryListing.ListFormat := flfDos;*)
  if FindFirst( '*.*',faAnyFile,SR ) = 0 then
  begin
    FTPLI := ADirectoryListing.Add;
    FTPLI.FileName := SR.Name;
    FTPLI.Size := SR.Size;
    if( SR.Attr and faDirectory ) = faDirectory then
      FTPLI.ItemType := ditDirectory
    else
      FTPLI.ItemType := ditFile;
    while FindNext( SR ) = 0 do
    begin
      FTPLI := ADirectoryListing.Add;
      FTPLI.FileName := SR.Name;
      FTPLI.Size := SR.Size;
      if( SR.Attr and faDirectory ) = faDirectory then
        FTPLI.ItemType := ditDirectory
      else
        FTPLI.ItemType := ditFile;
    end;
    FindClose( SR );
  end;
end;

procedure TMainFrm.FTPSrvGetFileSize(ASender: TIdFTPServerThread;
  const AFilename: String; var VFileSize: Int64);
var F : File;
begin
  AssignFile( F,AFileName );
  Reset( F );
  VFileSize := FileSize( F );
  CloseFile( F );
end;

procedure TMainFrm.FTPSrvConnect(AThread: TIdPeerThread);
begin
  LogMemo.Lines.Add( 'Connection from '+AThread.Connection.Socket.LocalName );
end;

procedure TMainFrm.FTPSrvStoreFile(ASender: TIdFTPServerThread;
  const AFileName: String; AAppend: Boolean; var VStream: TStream);
var FStream : TFileStream;
    CreateMode : Word;
begin
  if AAppend then
    CreateMode := fmOpenReadWrite
  else
    CreateMode := fmCreate;
  FStream := TFileStream.Create( AFileName,CreateMode );
  if AAppend then
    FStream.Position := FStream.Size;
  FStream.CopyFrom( VStream, VStream.Size );
end;

procedure TMainFrm.FTPSrvRetrieveFile(ASender: TIdFTPServerThread;
  const AFileName: String; var VStream: TStream);
begin
  VStream := TMemoryStream.Create;
  VStream.LoadFromFile( AFileName );
end;

procedure TMainFrm.FTPSrvDeleteFile(ASender: TIdFTPServerThread;
  const APathName: String);
begin
  DeleteFile( APathName );
end;

end.
0
 
LVL 2

Author Comment

by:SaLz
ID: 12709077
ok, we have got the listing.

procedure TForm1.FTPSrvListDirectory(ASender: TIdFTPServerThread;
  const APath: String; ADirectoryListing: TIdFTPListItems);
var
    item: TIdFTPListItem;
begin
  item := ADirectoryListing.Add;
  item.FileName := 'Hello.text';
  item.Size:=100000;
end;

how do we move from folder to folder? and display what location we are at?

if we have C:\pub\ as our location, if we navigate all the way though the subfolders to C:\pub\1\2\3\ how do we get the location?
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 12709156
That's *really* the case that you give a closer look to my code :-)

Cheers,

Andrew
0
 
LVL 2

Author Comment

by:SaLz
ID: 12710129
I've already taken a closer look at the code and nope.

it gives errors here saying LoadFromFile, undecared identifier. u missed anything out in uses? or types?

procedure TForm1.FTPSrvRetrieveFile(ASender: TIdFTPServerThread;
  const AFileName: String; var VStream: TStream);
begin
  VStream := TMemoryStream.Create;
  VStream.LoadFromFile( AFileName );
end;
=========

and on ListDirectory u missed the directory path, its just got '*.*'  so put in 'C:\' sure it lists, but I can't go anywhere else from that directory.

procedure TForm1.FTPSrvListDirectory(ASender: TIdFTPServerThread;
  const APath: String; ADirectoryListing: TIdFTPListItems);
var SR : TSearchRec;
    FTPLI : TidFTPListItem;
begin
//  GetFolderList( APath, FileNames );
(*  ADirectoryListing.LoadList( FileNames );
  ADirectoryListing.ListFormat := flfDos;*)
  if FindFirst( '*.*',faAnyFile,SR ) = 0 then
  begin
    FTPLI := ADirectoryListing.Add;
    FTPLI.FileName := SR.Name;
    FTPLI.Size := SR.Size;
    if( SR.Attr and faDirectory ) = faDirectory then
      FTPLI.ItemType := ditDirectory
    else
      FTPLI.ItemType := ditFile;
    while FindNext( SR ) = 0 do
    begin
      FTPLI := ADirectoryListing.Add;
      FTPLI.FileName := SR.Name;
      FTPLI.Size := SR.Size;
      if( SR.Attr and faDirectory ) = faDirectory then
        FTPLI.ItemType := ditDirectory
      else
        FTPLI.ItemType := ditFile;
    end;
    FindClose( SR );
  end;
end;
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 12903263
Hi,

You might want to use ChDir API to actually change folder.
But remember you're talking multiple clients here, so you would be best in keeping track of each folder in a
separate data object.

Look at TIdPeerThread for more informations.

Cheers,

Andrew
0
 
LVL 1

Assisted Solution

by:TiborKi
TiborKi earned 400 total points
ID: 13026073
You don't need to use Indy, becaouse it sucks!
Much better is if you use ICS!


http://www.overbyte.be/arch/icsbeta20050109.zip

Samples are inside, with full source code!

PS: If you solve problem by using ICS, please accept me!

Tibor
0
 
LVL 5

Expert Comment

by:DeerBear
ID: 13026265
The main advantage about Indy is that it's shipping with Delphi, thus can be found in any newer version of Delphi.
This might result in a good advantage over ICS, which is also a bit more complex to master than Indy.

Cheers,

Andrew
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month13 days, 22 hours left to enroll

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question