Code:
;================================================================
; Project LibCurl
; Title BrowseDownload.pb
; Author T.J.Roughton
; Date 19/11/2008
; Notes Browse & Download
;================================================================
XIncludeFile "RW_LibCurl_Res.pb"
XIncludeFile "RW_LibCurl_Inc.pb"
;- Window Constants
;
Enumeration
#FTPMAINWINDOW
EndEnumeration
;- Gadget Constants
;
Enumeration
#GAD_FTPBROWSERLIST
#GAD_FTPLOCATION
#GAD_OK
#GAD_CANCEL
#GAD_FTPUP
#GAD_GO
#GAD_DOWNLOAD
#GAD_PROGRESS
EndEnumeration
#DIRECTORY=1000
#FTPEOL=Chr(13)+Chr(10)
Structure S_FtpFile
filename.s
stream.l
EndStructure
Global ftpfile.S_FtpFile
Macro CurlError(value)
PeekS(curl_easy_strerror(value))
EndMacro
ProcedureC Curl_FTP_Debug(*cp.l,type.l,*buf.l,length.l,*ctx.l)
PrintN(PeekS(*buf))
ProcedureReturn 0
EndProcedure
ProcedureC LibCurl_WriteFunction(*ptr, Size, NMemB, *Stream)
Protected SizeProper.l = Size & 255
Protected NMemBProper.l = NMemB
rdata.s=PeekS(*ptr)
;
; LIST
;
; nline.l=CountString(rdata,#FTPEOL)
; For i=1 To nline
; line.s=StringField(rdata,i,#FTPEOL)
; idfile.b=#True
; For id=1 To 2
; If LCase(Mid(line,id,1))="d"
; idfile=#False
; Break
; EndIf
; Next
; If idfile=#False
; ;Debug "<DIR>"+Mid(line,10,Len(line))
; Else
; ;Debug "<FILE>"+Mid(line,10,Len(line))
; EndIf
; Debug ReplaceString(line," ","#")
; Next
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
iloop=CountString(rdata,Chr(10))
For i=1 To iloop
line.s=StringField(rdata,i,Chr(10))
numargs.l=CountString(line,";")+1
file.s=Trim(StringField(line,numargs,";"))
If (file<>"." And file<>"..")
idfile.b=#True
For numi=1 To numargs
WindowEvent()
flag.s=Trim(LCase(StringField(line,numi,";")))
If (FindString(flag,"type=dir",0) And file<>"")
AddGadgetItem(#GAD_FTPBROWSERLIST,-1,"*"+Chr(10)+file)
SetGadgetItemData(#GAD_FTPBROWSERLIST,CountGadgetItems(#GAD_FTPBROWSERLIST)-1,#DIRECTORY)
idfile.b=#False
ElseIf FindString(flag,"type=file",0)
filename.s=file
ElseIf FindString(flag,"size=",0)
filesize.s=RemoveString(flag,"size=",#PB_String_NoCase)
EndIf
Next
If (idfile=#True And filename<>"")
AddGadgetItem(#GAD_FTPBROWSERLIST,-1,Chr(10)+filename+Chr(10)+filesize)
EndIf
EndIf
Next
CompilerCase #PB_OS_Windows
iloop=CountString(rdata,#FTPEOL)
For i=1 To iloop
line.s=RemoveString(StringField(rdata,i,#FTPEOL),Chr(13))
numargs.l=CountString(line,";")+1
file.s=Trim(StringField(line,numargs,";"))
If (file<>"." And file<>"..")
idfile.b=#True
For numi=1 To numargs
WindowEvent()
flag.s=Trim(LCase(StringField(line,numi,";")))
If (FindString(flag,"type=dir",0) And file<>"")
AddGadgetItem(#GAD_FTPBROWSERLIST,-1,"*"+Chr(10)+file)
SetGadgetItemData(#GAD_FTPBROWSERLIST,CountGadgetItems(#GAD_FTPBROWSERLIST)-1,#DIRECTORY)
idfile.b=#False
ElseIf FindString(flag,"type=file",0)
filename.s=file
ElseIf FindString(flag,"size=",0)
filesize.s=RemoveString(flag,"size=",#PB_String_NoCase)
EndIf
Next
If (idfile=#True And filename<>"")
AddGadgetItem(#GAD_FTPBROWSERLIST,-1,Chr(10)+filename+Chr(10)+filesize)
EndIf
EndIf
Next
CompilerEndSelect
ProcedureReturn SizeProper * NMemBProper
EndProcedure
Procedure Curl_FTP_List(curl.l,ftp_url.s,dir.s,login.s, mdp.s, timeout.l = 1000)
url.s = "ftp://"+login+":"+mdp+"@"+ftp_url
If curl=0
curl = curl_easy_init()
EndIf
If curl
curl_easy_setopt(curl, #CURLOPT_URL, @url)
curl_easy_setopt(curl, #CURLOPT_TIMEOUT, timeout.l)
curl_easy_setopt(curl, #CURLOPT_CONNECTTIMEOUT, timeout.l)
;curl_easy_setopt(curl, #CURLOPT_FTPLISTONLY, #True)
curl_easy_setopt(curl, #CURLOPT_DEBUGFUNCTION, @Curl_FTP_Debug())
curl_easy_setopt(curl, #CURLOPT_VERBOSE, #True)
curl_easy_setopt(curl, #CURLOPT_WRITEFUNCTION, @LibCurl_WriteFunction())
;ftpdir.s="LIST "
ftpdir.s="MLSD "
curl_easy_setopt(curl, #CURLOPT_CUSTOMREQUEST,@ftpdir)
res = curl_easy_perform(curl)
If res <> #False
ProcedureReturn #False;
Else
ProcedureReturn curl
EndIf
Else
ProcedureReturn #False
EndIf
EndProcedure
ProcedureC.l Curl_FTP_Progress(clientp.l,total.d,dlnow.d,ultotal.d,ulnow.d)
WindowEvent()
SetGadgetAttribute(#GAD_PROGRESS,#PB_ProgressBar_Maximum,total)
SetGadgetState(#GAD_PROGRESS,dlnow)
ProcedureReturn 0
EndProcedure
ProcedureC.l FTP_WriteFile(buffer.l, size.l, nmemb.l, *Stream.S_FtpFile)
WindowEvent()
If *Stream And Not *Stream\stream
; Open file For writing
*Stream\stream = CreateFile(#PB_Any, *Stream\filename)
Debug "CreateFile()"
If Not *Stream\stream
; Failure, can't open file to write
ProcedureReturn -1
EndIf
EndIf
If IsFile(*Stream\stream)<>0
WriteData(*Stream\stream, buffer, (size & 255) * nmemb)
EndIf
ProcedureReturn (size & 255) * nmemb
EndProcedure
Procedure Curl_FTP_Download(curl.l,ftp_url.s,localfile.s,login.s, mdp.s, timeout.l = 1000)
url.s = "ftp://"+login+":"+mdp+"@"+ftp_url
ftpfile\filename=localfile ; local file
Debug url
Debug localfile
If curl
curl_easy_setopt(curl, #CURLOPT_URL, @url)
curl_easy_setopt(curl, #CURLOPT_WRITEFUNCTION, @FTP_WriteFile())
curl_easy_setopt(curl, #CURLOPT_WRITEDATA, ftpfile)
curl_easy_setopt(curl, #CURLOPT_NOPROGRESS, 0)
curl_easy_setopt(curl, #CURLOPT_PROGRESSFUNCTION,@Curl_FTP_Progress())
curl_easy_setopt(curl, #CURLOPT_VERBOSE, 0)
res = curl_easy_perform(curl)
If #CURLE_OK <> res
Debug ">"+Str(res)
EndIf
If ftpfile\stream
CloseFile(ftpfile\stream)
ftpfile\stream=0
SetGadgetState(#GAD_PROGRESS,0)
Else
Debug "!@##"
EndIf
EndIf
EndProcedure
Procedure.s DirUP(string.s)
dirdepth.l=CountString(string,"/")
For i=1 To Len(string)
If Mid(string,i,1)="/"
depthlvl=depthlvl+1
Debug Mid(string,1,i)
If depthlvl=dirdepth-1
ProcedureReturn Mid(string,1,i)
EndIf
EndIf
Next
EndProcedure
Procedure Open_FTPMAINWINDOW(address.s,user.s,pass.s,dir.s)
If OpenWindow(#FTPMAINWINDOW, 404, 316, 466, 500, "FTP Browser ("+address+")", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
ListIconGadget(#GAD_FTPBROWSERLIST, 5, 35, 455, 430, "", 25, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#GAD_FTPBROWSERLIST, 1, "File", 300)
AddGadgetColumn(#GAD_FTPBROWSERLIST, 2, "Size", 100)
StringGadget(#GAD_FTPLOCATION, 40, 5, 385, 25, "")
ButtonGadget(#GAD_FTPUP, 5, 5, 30, 25, "Up")
ButtonGadget(#GAD_GO, 430, 5, 30, 25, "Go")
ButtonGadget(#GAD_OK, 5, 470, 105, 25, "Ok")
ButtonGadget(#GAD_CANCEL, 355, 470, 105, 25, "Cancel")
ButtonGadget(#GAD_DOWNLOAD, 120, 470, 105, 25, "Download")
ProgressBarGadget(#GAD_PROGRESS,240,470,100,25,0,0)
EndIf
SetGadgetText(#GAD_FTPLOCATION,dir)
WindowEvent()
OpenConsole()
curl=Curl_FTP_List(0,address,dir,user,pass)
Repeat
event=WaitWindowEvent()
eventtype=EventType()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #GAD_DOWNLOAD
If GetGadgetItemData(#GAD_FTPBROWSERLIST,GetGadgetState(#GAD_FTPBROWSERLIST))<>#DIRECTORY
file.s=GetGadgetItemText(#GAD_FTPBROWSERLIST,GetGadgetState(#GAD_FTPBROWSERLIST),1)
dir.s=GetGadgetText(#GAD_FTPLOCATION)
Curl_FTP_Download(curl,address+dir+file,file,user,pass)
EndIf
Case #GAD_GO
ClearGadgetItems(#GAD_FTPBROWSERLIST)
dir.s=GetGadgetText(#GAD_FTPLOCATION)
If dir.s="" : dir="/" : EndIf
Curl_FTP_List(curl,address+dir+"/",dir,user,pass)
Case #GAD_FTPUP
ClearGadgetItems(#GAD_FTPBROWSERLIST)
dir.s=DirUP(GetGadgetText(#GAD_FTPLOCATION))
If dir.s="" : dir="/" : EndIf
Curl_FTP_List(curl,address+dir+"/",dir,user,pass)
SetGadgetText(#GAD_FTPLOCATION,dir)
Case #GAD_FTPBROWSERLIST
If eventtype=#PB_EventType_LeftDoubleClick
If GetGadgetItemData(#GAD_FTPBROWSERLIST,GetGadgetState(#GAD_FTPBROWSERLIST))=#DIRECTORY
newdir.s=GetGadgetItemText(#GAD_FTPBROWSERLIST,GetGadgetState(#GAD_FTPBROWSERLIST),1)
olddir.s=GetGadgetText(#GAD_FTPLOCATION)
dir.s=olddir+newdir+"/"
ClearGadgetItems(#GAD_FTPBROWSERLIST)
Curl_FTP_List(curl,address+dir+"/",dir,user,pass)
SetGadgetText(#GAD_FTPLOCATION,dir)
EndIf
EndIf
EndSelect
EndSelect
Until event=#PB_Event_CloseWindow
curl_easy_cleanup(curl)
CloseConsole()
EndProcedure
Open_FTPMAINWINDOW("<your address here>","anonymous","","/")