-
$ make
vai criar o executáveldownload
-
Listar o diretório de um servidor ftp.
./download ftp://[user:password@]host/url/para/diretorio
- Fazer download de um ficheiro num servidor ftp.
./download ftp://[user:password@]host/url/para/ficherio [novo-nome-para-o-ficheiro]
Como vamos ver nos exemplos, se um erro acontece e a ligação ao servidor está estabelecida,o programa é sempre capaz de desligar a conexão.
.
├── ftpPath.c
├── ftpPath.h
│
├── ftpReply.c
├── ftpReply.h
│
├── ftpClient.c
├── ftpClient.h
│
└── download.c
ftpPath.h
: api que dá parse a uma string contendo um URL de um servidor FTPftpReply.h
: api que permite criar mensagens e receber de respostas de várias linhas do servidor.ftpClient.h
: api que cria uma cliente FTP e implementa as funcoes download, e listing.download.c
: aplicacao de download que usa o cliente implementado.
ftpPath.h
define a api para dar parse a um URL de um servidor ftp:
typedef struct ftp_path FtpPath;
void printFtpPath(FtpPath* ftpPath);
int parseFTPPath(const char* ftpString, FtpPath* ftpPath);
#define NICEPRINT "------> "
#ifdef PRINT_COMMUNICATION
#define print_communication(...) printf(__VA_ARGS__)
#define print_reply(...) printf("%s", NICEPRINT);printf(__VA_ARGS__)
#else
#define print_communication(...)
#define print_reply(...)
#endif
extern char ftp_ReplyCode[4];
void ftpSafeReadMessage(int sockfd,char* buf,int size);
void ftpCreateMessage(char *dest, const char *command, const char *arg);
- No passo de compilação podemos não definir
PRINT_COMMUNICATION
e iremos assim desativar a impressão da comunicação entre o cliente e o servidor (para o caso de aplicações que queiram fazer algo mais complexo com este cliente) print_reply
é uma macro usada para imprimir as respostas do clienteftp_ReplyCode
é uma variável declarada comoextern
para imitar o estilo de códigos que usa alibc
com coisas comoerrno
eh_errno
, pode ser acedida depois da chamada aftpSafeReadMessage
.ftpSafeReadMessage
lê sempre toda a mensagem que o servidor mandou independentemente do tamanho do buffer dado ou a mensagem ser multiline.ftpCreateMessage
cria uma mensagem FTP emdest
com o comandando e o argumento dado.
#include "ftpPath.h"
int ftpInit(FtpPath *ftpPath);
int ftpQuit();
-
ftpInit(FtpPath *ftpPath)
: recebe um apontador para um FtpPath que é o resultado de dar parse de um URL FTP.A função implementa um cliente de FTP em modo passivo e retorna o file descriptor do socket de leitura. O que vai ler do socket depende do URL que lhe passamos:- Url de um ficheiro: o conteúdo do ficheiro.
- Url de um diretório: o conteudo do diretório.
Obtendo assim flexibilidade de dar
ls
de um diretório no servidor bem como fazer o download de um ficheiro do mesmo.
-
ftpQuit()
: fecha a conexao ftp enviandoquit
para o socket de controlo e fecha os dois sockets
Isto é tudo que um usuário do nosso cliente de ftp,
precisa de saber pois o resto é abstraido e está contido em ficheiros de implementacao (.c
) que
contem a maior parte da complexidade do trabalho.
Como providenciamos esta interface tão simples o seu uso acaba por ser bastante legível e idiomático:
Nestas 30 linhas de código:
- Damos parse à string que contem o URL
- Obtemos o fileDescriptor de onde vamos ler
- Se estivermos a trabalhar com um diretório damos print no terminal do seu conteudo.
- Se estivermos a trabalhar com um ficheiro criamos um ficheiro com o nome especificado no URL ou com outro nome que o user passe como argumento.
- Foram omitidos alguns detalhes de implementação nesta overview do código.