Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

BlackTDN :: ADVPL ~ Class TFTPClient : Combo I

ftp

Esse post inicia uma série sobre como transferir arquivos via FTP usando a Classe não documentada TFTPClient.

Muitos já devem ter usado as funções padrões para transferência de arquivos via FTP documentadas no TDN (Pasta: FTP).

O grande problema das funções é que nem todas elas estão documentadas: à exemplo da Função FTPQuote( cCommand ) que envia um subcomando FTP a ser executado no servidor. Além disso, as funções padrões, baseadas na classe TFTPClient não nos fornecem recursos para “depuração”.

Considerando que as funções padrões FTP* “encapsulam” o objeto instanciado pela classe TFTPClient vou usar essa última no código de exemplo para tornarná-lo mais rico em informações e, de certa forma, mais didático (assim espero). O original e suas dependências poderão ser obtidos ao clicar aqui.  Um detalhe importante sobre o código de exemplo é que todas as saídas se darão no console do appserver. Então execute em modo “debug” e acompanhe passo a passo a execução e observe as mensagens: elas são muito importantes para o bom entendimento do exemplo proposto.

Vale lembrar que, para o exemplo, usei um ambiente “controlado”; baseado no SO Windows XP SP3 (ambiente no qual montei e testei os exemplos). Sendo assim, e, dependendo do ambiente, o código necessitará de ajustes.

Para testar e demonstrar o exemplo utilizarei o SO Microsoft Windows XP SP3 (outra versão, que suporte FTP, poderá ser utilizada) e o totvs/protheus 10 (TOTVS - Build 7.00.111010P - Jan 20 2012 - 11:13:58).

Segue o código que será utilizado como base para a série sobre TFTPClient. Nos Próximos “combos” ele será destrinchado em suas partes mais importantes e fundamentais.

 

   1: #include "protheus.ch"
   2: #include "directry.ch"
   3:  
   4: #xtranslate USER PROCEDURE <p> => PROCEDURE U_<p>
   5:  
   6: #define CLSARR_CLASS_NAME          1
   7:  
   8: #define FTP_FILES_SAMPLES         10
   9: #define FTP_DIRECTORY_SAMPLES     10
  10:  
  11: //Define Path com arquivo de configuracao FTP. Redefina conforme necessidade
  12: #define FTP_PATH_INI_FILE          "C:\u_FTPSample\ini\u_FTPSample.ini"
  13:  
  14: Static __cCRLF := CRLF
  15:  
  16: /*
  17:      Procedure     : FtpSample()
  18:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
  19:      Data          : 05/05/2012
  20:      Uso           : Demonstrar o Uso da Classe FTPClient em ADVPL
  21:      Obs           : Testado em servidor FTP local baseado no Windows XP SP3
  22: */
  23: User Procedure FtpSample()
  24:  
  25:      Local baEval
  26:  
  27:      Local nBL
  28:      Local nEL
  29:      
  30:      Local nFile
  31:      Local nFiles
  32:  
  33:      Local cVar
  34:      Local cSource
  35:      Local cTarget
  36:  
  37:      Local aDirs
  38:      Local aFiles
  39:      Local aFTPCData
  40:      Local aDirectory
  41:      Local aFTPDirectory
  42:  
  43:      Local cFTPServer
  44:      Local nFTPPort
  45:      Local cFTPUser
  46:      Local cFTPPassword
  47:      Local lFTPFireWallMode
  48:      Local nFTPUsesIPConnection
  49:      Local nConnectTimeOut
  50:  
  51:      Local lTFINI             := FindFunction( "U_TFINI" )
  52:      Local lUTVarInfo         := FindFunction( "U_TVARINFONEW" )
  53:      Local nClsFTPClient      := aScan(__ClsArr(),{|x|x[CLSARR_CLASS_NAME]=="TFTPCLIENT"})
  54:      
  55:      //para que retorne exatamente como em disco em Directory()
  56:      //.NOT. lCaseSensitive em oFTPClient:Directory() estranho como misturam os conceitos (confuso isso)
  57:      Local lCaseSensitive     := .F.  
  58:  
  59:      Local oFTPIni
  60:      Local oFTPClient         := tFtpClient():New()
  61:      Local oFTPClassInfo
  62:  
  63:      Local cTempFile
  64:      Local cSubDirFTP
  65:      Local cDirFTPSample      := "\u_FtpSample\"
  66:     
  67:      Local cFTPCurDir         := ""
  68:  
  69:      Local cFTPCommand
  70:      Local nFTPCommand
  71:      Local cLastResponse
  72:  
  73:      Local nfHandle
  74:      Local nAttempts
  75:  
  76:      ConOut( "" , "[FTPClient][TEST][BEGIN]" )
  77:  
  78:      IF ( lUTVarInfo )
  79:           //Devido a ma formacao da Classe TFTPClient nao posso passar oFTPClient diretamente 
  80:           //para TVarInfo entao utilizo __ClsArr() para Obter as Propriedades e Metodos da Classe
  81:           oFTPClassInfo     := U_TVARINFONEW( __ClsArr()[nClsFTPClient] , "ClassFTPClient" )
  82:           ConOut( "" , "[FTPClient][TEST][oFTPClassInfo][BEGIN]" )
  83:           oFTPClassInfo:cCRLF := ""
  84:           ConOut( oFTPClassInfo:Echo() )
  85:           While oFTPClassInfo:GoNext()
  86:                ConOut( oFTPClassInfo:Echo() )
  87:           End While
  88:           ConOut( "" , "[FTPClient][TEST][oFTPClassInfo][END]" )
  89:      EndIF
  90:  
  91:      BEGIN SEQUENCE
  92:  
  93:           //Criando Diretorio "Local" Base
  94:           nAttempts := 0
  95:           While ( .NOT. lIsDir( cDirFTPSample ) )
  96:                MakeDir( cDirFTPSample )
  97:                IF lIsDir( cDirFTPSample )
  98:                     EXIT
  99:                EndIF
 100:                IF ( ++nAttempts > 10 )
 101:                     BREAK
 102:                EndIF
 103:                FTPSleep(NIL,500)
 104:           End While
 105:  
 106:           nFiles     := FTP_FILES_SAMPLES
 107:  
 108:           //Criando os arquivos no diretorio Principal
 109:           For nFile := 1 To nFiles
 110:               //Criando os arquivos nos subDiretorios
 111:               For nFile := 1 To nFiles
 112:                   cTempFile := CriaTrab( NIL , .F. )
 113:                   cTempFile += ".txt"
 114:                   nfHandle  := fCreate( cDirFTPSample + cTempFile )
 115:                   IF ( .NOT. ( nfHandle == -1 ) )
 116:                       //Crio um arquivo baseado nos Commandos Quote FTP
 117:                       aEval( FTPQCommands() , { |cCommand| fWrite( nfHandle , cCommand + __cCRLF ) } )
 118:                   ENDIF
 119:                   fClose( nfHandle )
 120:                Next nFile
 121:           Next nFile
 122:  
 123:           //Extraio um arquivo do RPO
 124:           Resource2File( "U_FTPSample.prg" , cDirFTPSample + "U_FTPSample.prg" )
 125:           //Extraio varias Imagens do RPO
 126:           cTarget := cDirFTPSample
 127:           baEval  := { |cResource,nI| IF(nI<=FTP_FILES_SAMPLES,Resource2File(cResource,cTarget+cResource),NIL) }
 128:           aEval(GetResArray("*.jpg"),baEval)
 129:  
 130:           //Criando subDiretorios e arquivos "Locais"
 131:           nEL      := FTP_DIRECTORY_SAMPLES
 132:           For nBL := 1 To nEL
 133:                cSubDirFTP := ( StrZero( nBL , 2 ) + "\" )
 134:                MakeDir( cDirFTPSample + cSubDirFTP )
 135:                IF lIsDir( cDirFTPSample + cSubDirFTP )
 136:                     //Criando os arquivos nos subDiretorios
 137:                     For nFile := 1 To nFiles
 138:                          cTempFile := CriaTrab( NIL , .F. )
 139:                          cTempFile += ".txt"
 140:                          nfHandle  := fCreate( cDirFTPSample + cSubDirFTP + cTempFile )
 141:                          IF ( .NOT. ( nfHandle == -1 ) )
 142:                              //Crio um arquivo baseado nos Commandos Quote FTP
 143:                              aEval( FTPQCommands() , { |cCommand| fWrite( nfHandle , cCommand + __cCRLF ) } )
 144:                          ENDIF
 145:                          fClose( nfHandle )
 146:                     Next nFile
 147:                     //Extraio um arquivo do RPO
 148:                     Resource2File( "U_FTPSample.prg" , cDirFTPSample + cSubDirFTP + "U_FTPSample.prg" )
 149:                     //Extraio varias Imagens do RPO
 150:                     cTarget := cDirFTPSample+cSubDirFTP
 151:                     baEval  := { |cResource,nI| IF(nI<=FTP_FILES_SAMPLES,Resource2File(cResource,cTarget+cResource),NIL) }
 152:                     aEval(GetResArray("*.jpg"),baEval)
 153:                EndIF
 154:           Next nBL
 155:  
 156:           IF ( lTFINI )
 157:      
 158:                //Atente para o Path do arquivo .ini de exemplo
 159:                oFTPIni := tFIni():New(FTP_PATH_INI_FILE)
 160:      
 161:                /*  
 162:                     u_FTPSample.ini DEFINITIONS BEGIN 
 163:      
 164:                     [FTP]
 165:                     Server=<name_server>
 166:                     Port=<port>
 167:                     User=<user>
 168:                     Password=<pwd>
 169:                     FireWallMode=<0|1>
 170:                     UsesIPConnection=<0|1>
 171:                     ConnectTimeOut=<nTimeOutValue>
 172:      
 173:                     u_FTPSample.ini DEFINITIONS END
 174:                     
 175:                */
 176:           
 177:                cFTPServer           := oFTPIni:GetPropertyValue("FTP","Server")
 178:                nFTPPort             := Val( oFTPIni:GetPropertyValue("FTP","Port") )
 179:                cFTPUser             := oFTPIni:GetPropertyValue("FTP","User")
 180:                cFTPPassword         := oFTPIni:GetPropertyValue("FTP","Password")
 181:      
 182:                lFTPFireWallMode     := ( Val( oFTPIni:GetPropertyValue("FTP","FireWallMode") ) == 1 )
 183:                nFTPUsesIPConnection := Val( oFTPIni:GetPropertyValue("FTP","UsesIPConnection") )
 184:                nConnectTimeOut      := Val( oFTPIni:GetPropertyValue("FTP","ConnectTimeOut") )
 185:                
 186:           Else
 187:  
 188:                cFTPServer           := "localhost"
 189:                nFTPPort             := 21
 190:                cFTPUser             := "anonymous"
 191:                cFTPPassword         := NIL
 192:  
 193:                lFTPFireWallMode     := 0
 194:                nFTPUsesIPConnection := 0
 195:                nConnectTimeOut      := 900
 196:  
 197:           EndIF     
 198:  
 199:           oFTPClient:bFireWallMode  := lFTPFireWallMode
 200:  
 201:           //Deveria ser Logico mas eh numerico
 202:           oFTPClient:bUsesIPConnection := nFTPUsesIPConnection
 203:           
 204:           oFTPClient:nConnectTimeOut   := nConnectTimeOut
 205:  
 206:           //Tenta efetuar conexao FTP
 207:           IF ( .NOT. FTPConnect(@oFTPClient,@cFTPServer,@nFTPPort,@cFTPUser,@cFTPPassword) )
 208:                BREAK
 209:           EndIF
 210:  
 211:           //Obtemos os valores das Propriedades da Classe TFTPCLIENT
 212:           ConOut( "" , "[FTPClient][TEST][Properties]" , "" )
 213:           aFTPCData       := __ClsArr()[nClsFTPClient][3]
 214:           Private oFTPVar := oFTPClient
 215:           nEL             := Len( aFTPCData )
 216:           For nBL := 1 To nEL
 217:                cVar := aFTPCData[nBL][1]
 218:                IF ( cVar $ "[ CERRORSTRING ]" )
 219:                     //"Undefined GetValueType value in file c:\advtec9\advpl\classinst.hpp at line 146"
 220:                     cLastResponse := "Undefined GetValueType value in file"
 221:                     ConOut( "[FTPClient][TEST][Properties][Property]["+cVar+"]["+cLastResponse+"]" )
 222:                     Loop
 223:                EndIF
 224:                ConOut( "[FTPClient][TEST][Properties][Property]["+cVar+"]["+cValToChar(oFTPVar&(":"+cVar))+"]" )
 225:           Next nBL
 226:  
 227:           oFTPVar := NIL
 228:  
 229:           ConOut( "" , "[FTPClient][TEST][FTPHelp]" )
 230:           //Verificamos quais comandos estao disponiveis 0 Ok, .not. 0 Error
 231:           nEL := Len( FTPQCommands() )
 232:           For nBL := 1 To nEL
 233:                cFTPCommand := FTPQCommands()[nBL]
 234:                nFTPCommand := oFTPClient:GetHelp(@cFTPCommand)
 235:                ConOut("[FTPClient][TEST][FTPHelp][FTPCommand]["+cFTPCommand+"]["+cValToChar(nFTPCommand)+"]")
 236:                cLastResponse := oFTPClient:GetLastResponse()
 237:                ConOut("[FTPClient][TEST][FTPHelp][FTPLastMsg]["+cLastResponse+"]")
 238:           Next nBL
 239:  
 240:           ConOut( "" , "[FTPClient][TEST][FTPHelp]" )
 241:           //Verificamos quais comandos nao estao disponiveis. 0 Ok, .not. 0 Error (Forcando o Erro)
 242:           nEL := Len( FTPQCommands() )
 243:           For nBL := 1 To nEL
 244:                cFTPCommand := "_*@"+FTPQCommands()[nBL]+"@*_"
 245:                nFTPCommand := oFTPClient:GetHelp(@cFTPCommand)
 246:                ConOut("[FTPClient][TEST][FTPHelp][FTPCommand]["+cFTPCommand+"]["+cValToChar(nFTPCommand)+"]")
 247:                cLastResponse := oFTPClient:GetLastResponse()
 248:                ConOut("[FTPClient][TEST][FTPHelp][FTPLastMsg]["+cLastResponse+"]")
 249:           Next nBL
 250:  
 251:           ConOut( "" , "[FTPClient][TEST][Quote]" )
 252:           //Verificamos Os Erros de FTPQuote. 0 Ok, .not. 0 Error
 253:           nEL := Len( FTPQCommands() )
 254:           For nBL := 1 To nEL
 255:                cFTPCommand := FTPQCommands()[nBL]
 256:                //Quote espera CRLF ao Final do Comando
 257:                nFTPCommand := FTPQuote(@oFTPClient,@cFTPCommand)
 258:                ConOut("[FTPClient][TEST][FTPQuote]["+cFTPCommand+"]["+cValToChar(nFTPCommand)+"]")
 259:                cLastResponse := oFTPClient:GetLastResponse()
 260:                ConOut("[FTPClient][TEST][FTPQuote][FTPLastMsg]["+cLastResponse+"]")
 261:                //Reconecto se QUIT ou REIN
 262:                IF ( ( nFTPCommand == 0 ) .and. ( cFTPCommand $ "[ QUIT ][ REIN ]" ) )
 263:                     //Tenta efetuar conexao FTP
 264:                     IF ( .NOT. FTPConnect(oFTPClient,cFTPServer,nFTPPort,cFTPUser,cFTPPassword) )
 265:                          BREAK
 266:                     EndIF
 267:                EndIF
 268:           Next nBL
 269:  
 270:           ConOut( "" , "[FTPClient][TEST][Quote]" )
 271:           //Verificamos Os Erros de FTPQuote. 0 Ok, .not. 0 Error (Forcando o Erro)
 272:           nEL := Len( FTPQCommands() )
 273:           For nBL := 1 To nEL
 274:                cFTPCommand := "_*@"+FTPQCommands()[nBL]+"@*_"
 275:                //Quote espera CRLF ao Final do Comando.
 276:                //Tem outro "Gato" aqui. Quote sempre retorna Zero mesmo o comando nao existindo
 277:                nFTPCommand := FTPQuote(@oFTPClient,@cFTPCommand)
 278:                ConOut("[FTPClient][TEST][FTPQuote]["+cFTPCommand+"]["+cValToChar(nFTPCommand)+"]")
 279:                cLastResponse := oFTPClient:GetLastResponse()
 280:                ConOut( "[FTPClient][TEST][FTPQuote][FTPLastMsg]["+cLastResponse+"]")
 281:           Next nBL
 282:  
 283:           //Redefino a Conexao 
 284:           IF ( .NOT. FTPConnect(@oFTPClient,@cFTPServer,@nFTPPort,@cFTPUser,@cFTPPassword) )
 285:                BREAK
 286:           EndIF
 287:  
 288:           //Obtenho o diretorio FTP Corrente
 289:           cFTPCurDir := FTPGetCurDir(@oFTPClient)
 290:           IF ( Empty( cFTPCurDir ) )
 291:                BREAK
 292:           EndIF
 293:  
 294:           //Obtenho os diretorios e arquivos "Locais"
 295:           aDirectory := Directory(cDirFTPSample+"*","D",NIL,@lCaseSensitive)
 296:  
 297:           aDirs      := Array(0)
 298:           aFiles     := Array(0)
 299:  
 300:           //Separo Diretorios de Arquivos
 301:           SplitFDir(@aDirectory,@aDirs,@aFiles,.F.)
 302:  
 303:           ConOut( "" , "[FTPClient][TEST][UpLoad][BEGIN]" , "" )
 304:  
 305:           //Demonstrar a Criacao do Diretorio via Quote e/ou MKDir 
 306:           IF ( cFTPCurDir == "/" )
 307:  
 308:                //Verifico se o Diretorio Existe
 309:                IF !( FTPChangeDir(@oFTPClient,@cDirFTPSample) )
 310:                     //Senao Tento Cria-lo
 311:                     IF !( FTPMakeDir(@oFTPClient,@cDirFTPSample) )
 312:                          BREAK
 313:                     EndIF
 314:                     IF !( FTPChangeDir(@oFTPClient,@cDirFTPSample) )
 315:                          BREAK
 316:                     EndIF
 317:                EndIF
 318:  
 319:                //UpLoad dos arquvios da pasta principal
 320:                nFiles := Len(aFiles)
 321:                For nFile := 1 To nFiles
 322:  
 323:                     cSource       := cDirFTPSample+aFiles[nFile][F_NAME]
 324:                     cTarget       := aFiles[nFile][F_NAME]
 325:                     //Envia o arquivo via SendFile
 326:                     nFTPCommand   := FTPSendFile(@oFTPClient,@cSource,@cTarget,@lFTPFireWallMode)
 327:  
 328:                     //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 329:                     aFTPDirectory := FTPDirectory(@oFTPClient,@cTarget,@lCaseSensitive,@lFTPFireWallMode)
 330:  
 331:                     //Verifico se o arquivo foi transferido "corretamente". Melhor seria via MD5.
 332:                     IF ( Len(aFTPDirectory) == 1 )
 333:                          IF ( Len(aFiles[nFile]) == Len(aFTPDirectory[1]) )     
 334:                               IF (;
 335:                                         ( aFiles[nFile][F_NAME] == aFTPDirectory[1][F_NAME] );
 336:                                         .and.;
 337:                                         ( aFiles[nFile][F_SIZE] == aFTPDirectory[1][F_SIZE] );
 338:                                    )
 339:                                    ConOut("[FTPClient][TEST][SendFile]["+cSource+"][OK]")
 340:                                    //Apago o arquivo "Local"
 341:                                    IF File( cSource )
 342:                                         fErase( cSource )
 343:                                    EndIF     
 344:                               EndIF          
 345:                          EndIF     
 346:                     EndIF
 347:  
 348:                Next nFile     
 349:  
 350:                //Criacao dos SubDiretorios e UpLoad dos arquivos
 351:                nEL := Len(aDirs)
 352:                For nBL := 1 To nEL
 353:  
 354:                     //Tenta ir para o Root
 355:                     IF !( FTPChangeDir(@oFTPClient,"/") )
 356:                          Loop
 357:                     EndIF
 358:  
 359:                     //Tenta ir para o diretorio base
 360:                     IF !( FTPChangeDir(@oFTPClient,cDirFTPSample) )
 361:                          Loop
 362:                     EndIF
 363:  
 364:                     //Verifico se o Diretorio Existe
 365:                     IF !( FTPChangeDir(@oFTPClient,aDirs[nBL]) )
 366:                          //Senao Tento Cria-lo
 367:                          IF !( FTPMakeDir(@oFTPClient,aDirs[nBL]) )
 368:                               Loop
 369:                          EndIF
 370:                          IF !( FTPChangeDir(@oFTPClient,aDirs[nBL]) )
 371:                               Loop
 372:                          EndIF
 373:                     EndIF
 374:  
 375:                     //Obtenho os arquivos "Locais"
 376:                     aFiles := Directory(cDirFTPSample+aDirs[nBL]+"\"+"*","A",NIL,@lCaseSensitive)
 377:                     //Envio o arquivo para o Servidor FTP
 378:                     nFiles := Len(aFiles)
 379:                     For nFile := 1 To nFiles
 380:                          
 381:                          cSource       := (cDirFTPSample+aDirs[nBL]+"\"+aFiles[nFile][F_NAME])
 382:                          cTarget       := aFiles[nFile][F_NAME]
 383:                          //Envia o arquivo via SendFile
 384:                          nFTPCommand   := FTPSendFile(@oFTPClient,@cSource,@cTarget,@lFTPFireWallMode)
 385:  
 386:                          //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 387:                          aFTPDirectory := FTPDirectory(@oFTPClient,@cTarget,@lCaseSensitive,@lFTPFireWallMode)
 388:  
 389:                          //Verifico se o arquivo foi transferido "corretamente". Melhor seria via MD5.
 390:                          IF ( Len(aFTPDirectory) == 1 )
 391:                               IF ( Len(aFiles[nFile]) == Len(aFTPDirectory[1]) )     
 392:                                    IF (;
 393:                                              ( aFiles[nFile][F_NAME] == aFTPDirectory[1][F_NAME] );
 394:                                              .and.;
 395:                                              ( aFiles[nFile][F_SIZE] == aFTPDirectory[1][F_SIZE] );
 396:                                         )
 397:                                         ConOut("[FTPClient][TEST][SendFile]["+cSource+"][OK]")
 398:                                         //Apago o arquivo "Local"
 399:                                         IF File( cSource )
 400:                                              fErase( cSource )
 401:                                         EndIF     
 402:                                    EndIF          
 403:                               EndIF     
 404:                          EndIF
 405:                
 406:                     Next nFile
 407:  
 408:                Next nBL
 409:  
 410:           EndIF
 411:  
 412:           ConOut( "" , "[FTPClient][TEST][UpLoad][END]" , "" )
 413:  
 414:           ConOut( "" , "[FTPClient][TEST][DownLoad][BEGIN]")
 415:  
 416:           //Tenta ir para o Root
 417:           IF !( FTPChangeDir(@oFTPClient,"/") )
 418:               BREAK
 419:           EndIF
 420:  
 421:           //Tenta ir para o diretorio base
 422:           IF !( FTPChangeDir(@oFTPClient,@cDirFTPSample) )
 423:               BREAK
 424:           EndIF
 425:  
 426:           //Obtenho os diretorios e arquivos do Servidor FTP
 427:           aFTPDirectory := FTPDirectory(@oFTPClient,"*",@lCaseSensitive,@lFTPFireWallMode)
 428:           //Separo Diretorios de Arquivos
 429:           SplitFDir(@aFTPDirectory,@aDirs,@aFiles,.T.)
 430:  
 431:           //Testo a Existencia do Diretorio "Local" Base
 432:           nAttempts := 0
 433:           While ( .NOT. lIsDir( cDirFTPSample ) )
 434:                MakeDir( cDirFTPSample )
 435:                IF lIsDir( cDirFTPSample )
 436:                     EXIT
 437:                EndIF
 438:                IF ( ++nAttempts > 10 )
 439:                     BREAK
 440:                EndIF
 441:                FTPSleep(@oFTPClient,500)
 442:           End While
 443:  
 444:           //DownLoad dos arquvios da pasta principal
 445:           nFiles := Len(aFiles)
 446:           For nFile := 1 To nFiles
 447:  
 448:                 cSource       := aFiles[nFile][F_NAME]
 449:                 cTarget       := ( cDirFTPSample+aFiles[nFile][F_NAME] )
 450:                 //Recebe o arquivo via ReceiveFile
 451:                 nFTPCommand   := FTPReceiveFile(@oFTPClient,@cSource,@cTarget,@lFTPFireWallMode)
 452:  
 453:                 //Tento Obter informacoes do arquivo Recebido em modo CaseSensitive
 454:                 aDirectory    := Directory(@cTarget,"A",NIL,@lCaseSensitive)
 455:  
 456:                 //Verifico se o arquivo foi transferido "corretamente". Melhor seria via MD5.
 457:                 IF ( Len(aDirectory) == 1 )
 458:                      IF ( Len(aFiles[nFile]) == Len(aDirectory[1]) )
 459:                           IF (;
 460:                                     ( aFiles[nFile][F_NAME] == aDirectory[1][F_NAME] );
 461:                                     .and.;
 462:                                     ( aFiles[nFile][F_SIZE] == aDirectory[1][F_SIZE] );
 463:                                )
 464:                                ConOut("[FTPClient][TEST][ReceiveFile]["+cTarget+"][OK]")
 465:                                //Apago o arquivo do Servidor FTP
 466:                                FTPfErase(@oFTPClient,@cSource,@lCaseSensitive,@lFTPFireWallMode)
 467:                           EndIF          
 468:                      EndIF     
 469:                 EndIF
 470:  
 471:           Next nFile     
 472:  
 473:           //Criacao dos SubDiretorios e DownLoad dos arquivos
 474:           nEL := Len(aDirs)
 475:           For nBL := 1 To nEL
 476:  
 477:                 //Tenta ir para o Root
 478:                 IF !( FTPChangeDir(@oFTPClient,"/") )
 479:                      Loop
 480:                 EndIF
 481:  
 482:                 //Tenta ir para o diretorio base
 483:                 IF !( FTPChangeDir(@oFTPClient,cDirFTPSample) )
 484:                      Loop
 485:                 EndIF
 486:  
 487:                 //Verifico se o Diretorio Existe
 488:                 IF !( FTPChangeDir(@oFTPClient,aDirs[nBL]) )
 489:                     Loop
 490:                 EndIF
 491:  
 492:                 //Testo a Existencia do Diretorio "Local"
 493:                 nAttempts := 0
 494:                 While ( .NOT. lIsDir( cDirFTPSample + aDirs[nBL] ) )
 495:                      MakeDir( cDirFTPSample + aDirs[nBL] )
 496:                      IF lIsDir( cDirFTPSample + aDirs[nBL] )
 497:                         EXIT
 498:                      EndIF
 499:                      IF ( ++nAttempts > 10 )
 500:                         BREAK
 501:                      EndIF
 502:                      FTPSleep(@oFTPClient,500)
 503:                 End While
 504:  
 505:                 //Obtenho os arquivos a Partir do Servidor FTP
 506:                 aFTPDirectory := FTPDirectory(@oFTPClient,"*",@lCaseSensitive,@lFTPFireWallMode)
 507:  
 508:                 //Separo Diretorios de Arquivos
 509:                 SplitFDir(@aFTPDirectory,NIL,@aFiles,.T.)
 510:  
 511:                 //Recebendo os arquivos a partir do Servidor FTP
 512:                 nFiles := Len(aFiles)
 513:                 For nFile := 1 To nFiles
 514:            
 515:                      cSource       := aFiles[nFile][F_NAME]
 516:                      cTarget       := (cDirFTPSample+aDirs[nBL]+"\"+aFiles[nFile][F_NAME])
 517:                      //Recebe o arquivo via ReceiveFile
 518:                      nFTPCommand   := FTPReceiveFile(@oFTPClient,@cSource,@cTarget,@lFTPFireWallMode)
 519:            
 520:                      //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 521:                      aDirectory    := Directory(@cTarget,"A",NIL,@lCaseSensitive)
 522:  
 523:                      //Verifico se o arquivo foi Recebido Corretamente "corretamente". Melhor seria via MD5.
 524:                      IF ( Len(aDirectory) == 1 )
 525:                           IF ( Len(aFiles[nFile]) == Len(aDirectory[1]) )
 526:                                IF (;
 527:                                          ( aFiles[nFile][F_NAME] == aDirectory[1][F_NAME] );
 528:                                          .and.;
 529:                                          ( aFiles[nFile][F_SIZE] == aDirectory[1][F_SIZE] );
 530:                                     )
 531:                                     ConOut("[FTPClient][TEST][ReceiveFile]["+cTarget+"][OK]")
 532:                                     //Apago o arquivo do Servidor FTP
 533:                                     FTPfErase(@oFTPClient,@cSource,@lCaseSensitive,@lFTPFireWallMode)
 534:                                EndIF
 535:                           EndIF     
 536:                      EndIF
 537:  
 538:                 Next nFile
 539:  
 540:           Next nBL
 541:  
 542:           ConOut( "" , "[FTPClient][TEST][DownLoad][END]")
 543:  
 544:      END SEQUENCE
 545:  
 546:      //Tenta ir para o Root
 547:      IF ( FTPChangeDir(@oFTPClient,"/") )
 548:           //Apagando os arquivos Temporarios no Servidor FTP
 549:           aFTPDirectory := FTPDirectory(@oFTPClient,"*.tmp",@lCaseSensitive,@lFTPFireWallMode)
 550:           //Separo Diretorios de Arquivos (Redundante aqui)
 551:           SplitFDir(@aFTPDirectory,NIL,@aFiles,.T.)
 552:           nFiles := Len( aFiles )
 553:           For nFile := 1 To nFiles
 554:                cSource := aFiles[nFile][F_NAME]
 555:                FTPfErase(@oFTPClient,@cSource,@lCaseSensitive,@lFTPFireWallMode)
 556:           Next nFile
 557:      EndIF
 558:  
 559:      ConOut( "" , "[FTPClient][TEST][FTPClose]" )
 560:      cFTPCommand := "QUIT"
 561:      FTPQuote(@oFTPClient,@cFTPCommand)
 562:      oFTPClient:Close()
 563:  
 564:      ConOut( "" , "[FTPClient][TEST][FreeObj]" )
 565:      oFTPClient     := FreeObj( oFTPClient )
 566:  
 567:      IF ( lUTVarInfo )
 568:           oFTPClassInfo:Close()
 569:           oFTPClassInfo := FreeObj( oFTPClassInfo )
 570:      EndIF
 571:  
 572:      IF ( lTFINI )
 573:           oFTPIni := FreeObj( oFTPIni )
 574:      EndIF
 575:  
 576:      ConOut( "[FTPClient][TEST][END]" , "" )
 577:  
 578: Return
 579:  
 580: /*
 581:      Funcao        : FTPConnect
 582:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 583:      Data          : 05/05/2012
 584:      Uso           : Tentar efetar uma conexao FTP
 585: */
 586: Static Function FTPConnect(oFTPClient,cFTPServer,nFTPPort,cFTPUser,cFTPPassword)
 587:  
 588:      Local cLastResponse
 589:  
 590:      Local nFTpCommand 
 591:      Local lFTPConnect
 592:  
 593:      oFTPClient:Close()
 594:  
 595:      ConOut( "" , "[FTPClient][TEST][FTPConnect]" )
 596:  
 597:      nFTpCommand := oFTPClient:FTPConnect(@cFTPServer,@nFTPPort,@cFTPUser,@cFTPPassword)
 598:      lFTPConnect := ( nFTPCommand == 0 )
 599:  
 600:      IF ( lFTPConnect )
 601:           ConOut( "[FTPClient][TEST][FTPConnect][OK]["+cValToChar(nFTPCommand)+"]" , "" )                   
 602:           cLastResponse := oFTPClient:GetLastResponse()
 603:           ConOut( "[FTPClient][TEST][FTPConnect][OK]["+Ltrim(Str(nFTPCommand))+"]["+cLastResponse+"]")
 604:     Else     
 605:           /*
 606:                Tem um Gato aqui. cErrorString deveria ser String mas esta definida como Number
 607:                Undefined GetValueType value in file c:\advtec9\advpl\classinst.hpp at line 146
 608:  
 609:                Win NT/2000
 610:  
 611:                [INFO ][SERVER] [SMARTHEAP] Registering Tasks...
 612:                ***  TOTVS S.A.  ***
 613:                ***   www.totvs.com.br    ***
 614:                TOTVS - Build 7.00.111010P - Jan 20 2012 - 11:13:58
 615:           */     
 616:           * ConOut( "[FTPClient][TEST][FTPConnect][Error]["+oFTPClient:cErrorString+"]") 
 617:           cLastResponse := oFTPClient:GetLastResponse()
 618:           ConOut( "[FTPClient][TEST][FTPConnect][Error]["+Ltrim(Str(nFTPCommand))+"]["+cLastResponse+"]")
 619:      EndIF
 620:  
 621: Return( lFTPConnect )
 622:  
 623: /*
 624:      Function      : FTPGetCurDir()
 625:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 626:      Data          : 05/05/2012
 627:      Uso           : Retorna o Diretorio FTP Corrente
 628: */
 629: Static Function FTPGetCurDir(oFTPClient)
 630:  
 631:      Local cLastResponse
 632:      Local cFTPCurDir
 633:      Local cFTPCommand
 634:      Local nFTPCommand
 635:  
 636:      Static __lGetDirQuote := .F.
 637:  
 638:      ConOut( "" , "[FTPClient][TEST][GetCurDir]" )
 639:  
 640:      IF ( __lGetDirQuote )
 641:           __lGetDirQuote     := .F.
 642:           //Obtenho o diretorio corrente via XPWD em Quote
 643:           cFTPCommand        := "XPWD"
 644:           nFTPCommand        := FTPQuote(@oFTPClient,@cFTPCommand)
 645:           cLastResponse      := oFTPClient:GetLastResponse()
 646:           IF ( SubStr( cLastResponse , 1 , 3 ) == "257" )
 647:                cFTPCurDir    := StrToKArr( cLastResponse , '"' )[2]
 648:           EndIF     
 649:      Else
 650:           __lGetDirQuote     := .T.
 651:           //Obtenho o diretorio corrente via GetCurDir
 652:           nFTPCommand := oFTPClient:GetCurDir(@cFTPCurDir)
 653:      EndIF
 654:  
 655:      DEFAULT cFTPCurDir     := ""
 656:      
 657:      IF ( .NOT. ( nFTPCommand == 0 ) .or. .NOT. ( "/" $ cFTPCurDir ) )
 658:           /*
 659:                Tem um Gato aqui. cErrorString deveria ser String mas esta definida como Number
 660:                Undefined GetValueType value in file c:\advtec9\advpl\classinst.hpp at line 146
 661: 
 662:                Win NT/2000
 663: 
 664:                [INFO ][SERVER] [SMARTHEAP] Registering Tasks...
 665:                ***  TOTVS S.A.  ***
 666:                ***   www.totvs.com.br    ***
 667:                TOTVS - Build 7.00.111010P - Jan 20 2012 - 11:13:58
 668:           */     
 669:           * ConOut( "[FTPClient][TEST][GetCurDir][Error]["+oFTPClient:cErrorString+"]") 
 670:           ConOut(  "[FTPClient][TEST][GetCurDir][Error]["+Ltrim(Str(nFTPCommand))+"]")
 671:           cLastResponse   := oFTPClient:GetLastResponse()
 672:           ConOut(  "[FTPClient][TEST][FTPLastMsg][Error]["+Ltrim(Str(nFTPCommand))+"]["+cLastResponse+"]")
 673:           cFTPCurDir     := ""
 674:      Else
 675:           ConOut( "[FTPClient][TEST][GetCurDir]["+cFTPCurDir+"]")
 676:      EndIF
 677:  
 678: Return( cFTPCurDir )
 679:  
 680: /*
 681:      Function      : FTPChangeDir()
 682:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 683:      Data          : 05/05/2012
 684:      Uso           : Tenta Modificar o Diretorio Corrente
 685: */
 686: Static Function FTPChangeDir(oFTPClient,cDir)
 687:  
 688:      Local cTmp
 689:      Local cFTPCommand
 690:      Local nFTPCommand
 691:      
 692:      Local lOk             := .F.
 693:  
 694:      Static __lChgDirQuote := .F.
 695:  
 696:      IF ( __lChgDirQuote )
 697:           __lChgDirQuote   := .F.
 698:           //Tenta Modificar o Diretorio Corrente usando CWD em Quote
 699:           cFTPCommand := ( "CWD " + cDir )
 700:           nFTPCommand := FTPQuote(@oFTPClient,@cFTPCommand)
 701:      Else
 702:           __lChgDirQuote   := .T.
 703:           //Tenta Modificar o Diretorio Corrente usando ChDir
 704:           nFTPCommand := oFTPClient:ChDir(cDir)
 705:      EndIF
 706:  
 707:      lOk     := ( FTPGetCurDir(@oFTPClient) == cDir )
 708:      IF !( lOk )
 709:           cTmp := StrTran(cDir,"\","/")
 710:           IF ( SubStr(cTmp,-1) == "/" )
 711:                cTmp  := SubStr(cTmp,1,(Len(cTmp)-1))
 712:           EndIF
 713:           lOk  := ( FTPGetCurDir(@oFTPClient) == cTmp )
 714:           IF !( lOk )
 715:                cTmp  := FTPGetCurDir(@oFTPClient)
 716:                lOk   := ( SubStr( cTmp , -Len( cDir ) ) == cDir )
 717:           EndIF
 718:      EndIF
 719:  
 720: Return( lOk )
 721:  
 722: /*
 723:      Function      : FTPMakeDir()
 724:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 725:      Data          : 05/05/2012
 726:      Uso           : Tenta Criar um Diretorio
 727: */
 728: Static Function FTPMakeDir(oFTPClient,cDir)
 729:  
 730:      Local cLastDir       := FTPGetCurDir(oFTPClient)
 731:      Local cFTPCommand
 732:      
 733:      Local lOK            := .F.
 734:  
 735:      Static __lMkDirQuote := .F.
 736:  
 737:      IF ( __lMkDirQuote )
 738:           __lMkDirQuote   := .F.
 739:           //Tenta Criar Diretorio usando o comando MDK em Quote
 740:           cFTPCommand     := ( "MKD " + cDir )
 741:           FTPQuote(@oFTPClient,@cFTPCommand)
 742:      Else
 743:           __lMkDirQuote   := .T.
 744:           //Tenta Criar Diretorio usando MKDir
 745:           oFTPClient:MKDir(cDir)
 746:      EndIF
 747:  
 748:      lOK := FTPChangeDir(oFTPClient,@cDir)
 749:  
 750:      FTPChangeDir(oFTPClient,"/")
 751:      FTPChangeDir(oFTPClient,@cLastDir)
 752:  
 753: Return( lOK )
 754:  
 755: /*
 756:      Function      : FTPQuote()
 757:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 758:      Data          : 05/05/2012
 759:      Uso           : Envia um comando via Quote
 760: */
 761: Static Function FTPQuote(oFTPClient,cFTPCommand)
 762: Return(oFTPClient:Quote(cFTPCommand+__cCRLF))
 763:  
 764: /*
 765:      Function      : FTPDirectory()
 766:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 767:      Data          : 05/05/2012
 768:      Uso           : Retorna informacao de Diretorio FTP
 769: */
 770: Static Function FTPDirectory(oFTPClient,cMask,lCaseSensitive,lFTPFireWallMode)
 771:  
 772:      Local aFTPDirectory
 773:  
 774:      Local cLastResponse
 775:  
 776:      DEFAULT lCaseSensitive     := .F.
 777:  
 778:      //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 779:      aFTPDirectory      := oFTPClient:Directory( @cMask , ( .NOT. lCaseSensitive ) )
 780:      IF ( Len(aFTPDirectory) == 0 )
 781:           cLastResponse := oFTPClient:GetLastResponse()
 782:           IF ( "500" $ cLastResponse )
 783:                //Altero para Modo Passivo
 784:                oFTPClient:bFireWallMode := .T.
 785:                //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 786:                aFTPDirectory            := oFTPClient:Directory( @cMask , ( .NOT. lCaseSensitive ) )
 787:                //Restaura Modo Anterior
 788:                oFTPClient:bFireWallMode := lFTPFireWallMode
 789:           EndIF
 790:      EndIF     
 791:  
 792:      cLastResponse := oFTPClient:GetLastResponse()
 793:      ConOut("[FTPClient][TEST][FTPDirectory]["+cLastResponse+"]")
 794:  
 795: Return( aFTPDirectory )
 796:  
 797: /*
 798:      Function      : FTPErase()
 799:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 800:      Data          : 05/05/2012
 801:      Uso           : Tenta apagar arquivo no Servidor FTP
 802: */
 803: Static Function FTPfErase(oFTPClient,cFile,lCaseSensitive,lFTPFireWallMode)
 804:  
 805:      Local cFTPCommand
 806:      Local nFTPCommand
 807:  
 808:      Local lOK             := .F.
 809:  
 810:      Static __lFTPDelQuote := .F.
 811:  
 812:      IF ( __lFTPDelQuote )
 813:           __lFTPDelQuote   := .F.
 814:           //Tenta Excluir Diretorio usando o comando DELE em Quote
 815:           cFTPCommand      := ( "DELE " + cFile )
 816:           nFTPCommand      := FTPQuote(@oFTPClient,@cFTPCommand)
 817:      Else
 818:           __lFTPDelQuote   := .T.
 819:           //Tenta Excluir Diretorio usando DeleteFile
 820:           nFTPCommand      := oFTPClient:DeleteFile( cFile )
 821:      EndIF
 822:  
 823:      FTPSleep(@oFTPClient,200)
 824:  
 825:      cLastResponse := oFTPClient:GetLastResponse()
 826:      ConOut("[FTPClient][TEST][FTPfErase]["+cValToChar(nFTPCommand)+"]["+cLastResponse+"]")
 827:  
 828:      lOK := ( Len( FTPDirectory(@oFTPClient,@cFile,@lCaseSensitive,@lFTPFireWallMode) ) == 0 )
 829:  
 830: Return( lOK )
 831:  
 832: /*
 833:      Function      : FTPSendFile()
 834:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 835:      Data          : 05/05/2012
 836:      Uso           : Tenta efetuar Upload de informacao "Local" para Diretorio FTP
 837: */
 838: Static Function FTPSendFile(oFTPClient,cLocalFile,cFTPFile,lFTPFireWallMode)
 839:  
 840:      Local cLastResponse
 841:  
 842:      Local lOk             := .F.
 843:  
 844:      Local nFTPCommand       := -1
 845:  
 846:      //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 847:      nFTPCommand   := oFTPClient:SendFile(@cLocalFile,@cFTPFile)
 848:      IF ( .NOT. ( nFTPCommand == 0 ) )
 849:           cLastResponse := oFTPClient:GetLastResponse()
 850:           IF ( "500" $ cLastResponse )
 851:                //Altero para Modo Passivo
 852:                oFTPClient:bFireWallMode := .T.
 853:                //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 854:                nFTPCommand              := oFTPClient:SendFile(@cLocalFile,@cFTPFile)
 855:                //Restaura Modo Anterior
 856:                oFTPClient:bFireWallMode := lFTPFireWallMode
 857:           EndIF
 858:      EndIF
 859:  
 860:      FTPSleep(@oFTPClient,200)
 861:  
 862:      cLastResponse := oFTPClient:GetLastResponse()
 863:      ConOut("[FTPClient][TEST][FTPSendFile]["+cValToChar(nFTPCommand)+"]["+cLastResponse+"]")
 864:  
 865:      lOk := ( nFTPCommand == 0 )
 866:  
 867: Return( lOk )
 868:  
 869: /*
 870:      Function      : FTPReceiveFile()
 871:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 872:      Data          : 05/05/2012
 873:      Uso           : Tenta efetuar Download de informacao de Diretorio FTP
 874: */
 875: Static Function FTPReceiveFile(oFTPClient,cFTPFile,cLocalFile,lFTPFireWallMode)
 876:  
 877:      Local cLastResponse
 878:      
 879:      Local lOk             := .F.
 880:  
 881:      Local nFTPCommand       := -1
 882:  
 883:      //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 884:      nFTPCommand   := oFTPClient:ReceiveFile(@cFTPFile,@cLocalFile)
 885:      IF ( .NOT. ( nFTPCommand == 0 ) )
 886:           cLastResponse := oFTPClient:GetLastResponse()
 887:           IF ( "500" $ cLastResponse )
 888:                //Altero para Modo Passivo
 889:                oFTPClient:bFireWallMode := .T.
 890:                //Tento Obter informacoes do arquivo enviado em modo CaseSensitive
 891:                nFTPCommand              := oFTPClient:ReceiveFile(@cFTPFile,@cLocalFile)
 892:                //Restaura Modo Anterior
 893:                oFTPClient:bFireWallMode := lFTPFireWallMode
 894:           EndIF
 895:      EndIF     
 896:  
 897:      FTPSleep(@oFTPClient,200)
 898:  
 899:      cLastResponse := oFTPClient:GetLastResponse()
 900:      ConOut("[FTPClient][TEST][FTPReceiveFile]["+cValToChar(nFTPCommand)+"]["+cLastResponse+"]")
 901:  
 902:      lOk := ( nFTPCommand == 0 )
 903:  
 904: Return( lOk )
 905:  
 906: /*
 907:      Function      : FTPSleep()
 908:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 909:      Data          : 05/05/2012
 910:      Uso           : Sleep com Controle de TimeOut do FTP
 911: */
 912: Static Function FTPSleep(oFTPClient,nSleep)
 913:     Local nFTPSleep
 914:     DEFAULT nSleep                     := 0
 915:     IF ( ValType(oFTPClient) == "O" )
 916:         DEFAULT oFTPClient:nConnectTimeOut := 120
 917:         nFTPSleep      := ( oFTPClient:nConnectTimeOut / 2 )
 918:     Else
 919:         nFTPSleep      := nSleep
 920:     EndIF    
 921:     nSleep             := Min( nSleep , nFTPSleep )
 922: Return(Sleep(nSleep))
 923:  
 924: /*
 925:      Function      : SplitFDir
 926:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 927:      Data          : 05/05/2012
 928:      Uso           : Separa a Estrutura de aDirectory em aDirs e a Files
 929: */
 930: Static Procedure SplitFDir(aDirectory,aDirs,aFiles,lFTP)
 931:  
 932:     Local nAT
 933:  
 934:     DEFAULT aDirs  := Array(0)
 935:     DEFAULT aFiles := Array(0)
 936:     DEFAULT lFTP   := .F.
 937:  
 938:     //Obtenho a Estrutura de Diretorios
 939:     nAT   := 0
 940:     aSize( aDirs   , 0 )
 941:     While ( ( nAT := aScan( aDirectory , { |aDir| ( aDir[F_ATTR] == "D" ) } , ++nAT ) ) > 0 )
 942:         IF ( .NOT.( ( aDirectory[nAT][F_NAME] == "." ) .or. ( aDirectory[nAT][F_NAME] == ".." ) ) )
 943:             aAdd( aDirs , aDirectory[nAT][F_NAME] )
 944:         EndIF
 945:     End While
 946:  
 947:     //Obtenho os arquivos
 948:     nAT    := 0
 949:     aSize( aFiles , 0 )
 950:     IF ( lFTP )
 951:         While ( ( nAT := aScan( aDirectory , { |aDir| Empty( aDir[F_ATTR] ) .or. ( aDir[F_ATTR] == "A" ) } , ++nAT ) ) > 0 )
 952:               aAdd( aFiles , aDirectory[nAT] )
 953:         End While  
 954:     Else
 955:         While ( ( nAT := aScan( aDirectory , { |aDir| ( aDir[F_ATTR] == "A" ) } , ++nAT ) ) > 0 )
 956:               aAdd( aFiles , aDirectory[nAT] )
 957:         End While
 958:     EndIF
 959:  
 960:     aSize( aDirectory , 0 )
 961:  
 962: Return
 963:  
 964: /*
 965:      Funcao        : FTPQCommands()
 966:      Autor         : Marinaldo de jesus [ www.blacktdn.com.br ]
 967:      Data          : 05/05/2012
 968:      Uso           : Retornar os Quote Commands Validos Base Windows XP SP3
 969:  
 970:      Obs.: 
 971:      Alguns Detalhes e explicacoes sobre os comandos poderao ser obitidos na url abaixo
 972:      http://www.ipswitch.com/support/ws_ftp-server/guide/v5/a_ftpref3.html
 973: */
 974: Static Function FTPQCommands()
 975:      Static __aFTPCmd
 976:      IF ( __aFTPCmd == NIL )
 977:           __aFTPCmd := Array(0)
 978:           aAdd( __aFTPCmd , "ABOR" )
 979:           aAdd( __aFTPCmd , "ACCT" )
 980:           aAdd( __aFTPCmd , "ALLO" )
 981:           aAdd( __aFTPCmd , "APPE" )
 982:           aAdd( __aFTPCmd , "CDUP" )
 983:           aAdd( __aFTPCmd , "CWD"  )
 984:           aAdd( __aFTPCmd , "DELE" )
 985:           aAdd( __aFTPCmd , "HELP" )
 986:           aAdd( __aFTPCmd , "LIST" )
 987:           aAdd( __aFTPCmd , "MDTM" )
 988:           aAdd( __aFTPCmd , "MKD"  )
 989:           aAdd( __aFTPCmd , "MODE" )
 990:           aAdd( __aFTPCmd , "NLST" )
 991:           aAdd( __aFTPCmd , "NOOP" )
 992:           aAdd( __aFTPCmd , "PASS" )
 993:           aAdd( __aFTPCmd , "PASV" )
 994:           aAdd( __aFTPCmd , "PORT" )
 995:           aAdd( __aFTPCmd , "PWD"  )
 996:           aAdd( __aFTPCmd , "QUIT" )
 997:           aAdd( __aFTPCmd , "REIN" )
 998:           aAdd( __aFTPCmd , "REST" )
 999:           aAdd( __aFTPCmd , "RETR" )
1000:           aAdd( __aFTPCmd , "RMD"  )
1001:           aAdd( __aFTPCmd , "RNFR" )
1002:           aAdd( __aFTPCmd , "RNTO" )
1003:           aAdd( __aFTPCmd , "SITE" )
1004:           aAdd( __aFTPCmd , "SIZE" )
1005:           aAdd( __aFTPCmd , "SMNT" )
1006:           aAdd( __aFTPCmd , "STAT" )
1007:           aAdd( __aFTPCmd , "STOR" )
1008:           aAdd( __aFTPCmd , "STOU" )
1009:           aAdd( __aFTPCmd , "STRU" )
1010:           aAdd( __aFTPCmd , "SYST" )
1011:           aAdd( __aFTPCmd , "TYPE" )
1012:           aAdd( __aFTPCmd , "USER" )
1013:           aAdd( __aFTPCmd , "XCUP" )
1014:           aAdd( __aFTPCmd , "XCWD" )
1015:           aAdd( __aFTPCmd , "XMKD" )
1016:           aAdd( __aFTPCmd , "XPWD" )
1017:           aAdd( __aFTPCmd , "XRMD" )
1018:      ENDIF
1019: Return( __aFTPCmd )

… continua


[]s
иαldσ dj

Comentários

  1. Muito bom mesmo... agora
    só nao encontrei como que eu sei as permissoes que eu tenho dentro do servidor ftp, como recortar ou copiar
    sabe se tem Naldo?

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

BlackTDN :: RLeg ~ Desvendando a Função ParamBox

Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA

BlackTDN :: Customizando a interface de Login no Protheus e by You

A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã