cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: The problem of implementing ftp client function: listDirContents()

From: HU Chengzhe <Chengzhe.Hu_at_alcatel-sbell.com.cn>
Date: Mon, 23 Aug 2010 16:15:34 +0800

Hello,
    Is there anyone can answer my question? I am urgently looking forward to your answer.

Thank you.

Best Regards,
Arkie

> _____________________________________________
> From: HU Chengzhe
> Sent: 2010823 9:06
> To: curl-library_at_cool.haxx.se
> Subject: The problem of implementing ftp client function: listDirContents()
>
> Hello,
> when I plan to implement some ftp client functions based on libcurl, I encounter some problems:
>
> listDirContents(), this function is expected to return the detail file informations of the specific directory, such as like this:
> -r--r--r-- 1 oamops oamgroup 9539 Jul 9 2008 .alias_oam
>
> my code is as follow:
> _______________________________________________________________________________
> struct FtpFile {
> const char *filename;
> FILE *stream;
> };
>
> static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
> {
> struct FtpFile *out=(struct FtpFile *)stream;
> if(out && !out->stream) {
> /* open file for writing */
> out->stream=fopen(out->filename, "wb");
> if(!out->stream)
> return -1; /* failure, can't open file to write */
> }
> return fwrite(buffer, size, nmemb, out->stream);
> }
>
> struct MemoryStruct {
> char *memory;
> size_t size;
> };
>
> static void *myrealloc(void *ptr, size_t size);
>
> static void *myrealloc(void *ptr, size_t size)
> {
> if(ptr)
> return realloc(ptr, size);
> else
> return malloc(size);
> }
>
> static size_t
> WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
> {
> size_t realsize = size * nmemb;
> struct MemoryStruct *mem = (struct MemoryStruct *)data;
>
> mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
> if (mem->memory) {
> memcpy(&(mem->memory[mem->size]), ptr, realsize);
> mem->size += realsize;
> mem->memory[mem->size] = 0;
> }
> return realsize;
> }
>
> int main(void){
> CURL *curl;
> CURLcode res;
> struct FtpFile ftpfile={
> "./dadafile", /* name to store the file as if succesful */
> NULL
> };
>
> curl_global_init(CURL_GLOBAL_DEFAULT);
>
>
> struct MemoryStruct chunk;
>
> chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
> chunk.size = 0;
>
> curl = curl_easy_init();
> if(curl) {
>
> curl_easy_setopt(curl, CURLOPT_URL,
> "ftp://137.212.232.82");
> //set username for transfer
> curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
>
> //set password for transfer
> curl_easy_setopt(curl, CURLOPT_PASSWORD, "user");
>
> struct curl_slist *headerlist = NULL;
> const char s[] = "PWD";
> const char s1[] = "LIST ";
> const char s2[] = "CWD /home/oamops/cid";
> headerlist = curl_slist_append(headerlist, s);
> headerlist = curl_slist_append(headerlist, s2);
> headerlist = curl_slist_append(headerlist, s1);
> curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
>
> /* As I am not sure the return list would be by header or data,
> * I try the two ways at same time
> */
> curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WriteMemoryCallback);
> curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)&chunk);
>
> curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
> curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
>
>
> res = curl_easy_perform(curl);
>
> /* always cleanup */
> curl_easy_cleanup(curl);
>
> if(CURLE_OK != res) {
> /* we failed */
> fprintf(stderr, "curl told us %d\n", res);
> }
> }
> if(ftpfile.stream)
> fclose(ftpfile.stream); /* close the local file */
>
> cout<<"#####################"<<endl;
> cout<<"chunk.size: "<<chunk.size<<endl;
> cout<<"chunk.memory: "<<chunk.memory<<endl;
>
> curl_global_cleanup();
>
> }
> _________________________________________________________________>
> expected result: the list of file information for directory "/home/oamops/cid" would display in file datafile or print to stdout.
> actual result:
> the context in file datafile is the list of file information for ftp server root path ("home/oamops"), not the "/home/oamops/cid" .
> the stdout is:
> chunk.size: 595
> chunk.memory: 220-Restricted Access System
> 220-
> 220 zsups382 FTP server ready.
> 331 Password required for oamops.
> 230 User oamops logged in.
> 257 "/home/oamops" is current directory.
> 229 Entering Extended Passive Mode (|||46616|)
> 200 Type set to A.
> 150 Opening ASCII mode data connection for /bin/ls.
> 226 Transfer complete.
> 257 "/home/oamops" is current directory.
> 425 Can't build data connection: Connection refused.
> 221-You have transferred 0 bytes in 0 files.
> 221-Total traffic for this session was 3409 bytes in 1 transfers.
> 221-Thank you for using the FTP service on zsups382.
> 221 Goodbye.
>
> so my question is:
> 1) why the actual result is not same as expected result?
> 2) Or Is there some code wrong?
> 3) My thought about implementation of listDirContents() is right? Is there some way is more convenient than mine?
>
> Thank you for answer in advanced.
>
> Best Regards,
> Arkie
>
>

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2010-08-23