Advertisement
Guest User

Libcurl

a guest
Dec 31st, 2013
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.27 KB | None | 0 0
  1. void Uploader::QueueUpload(const wxString& path, bool isFile, const wxString& localpath)
  2. {
  3.     curl_multi_setopt(m_curlMultiHandle, CURLMOPT_MAXCONNECTS, 1);//TODO: Set from Config
  4.  
  5.     wxString url;
  6.     if(!isFile && !path.EndsWith("/"))
  7.     {
  8.         //dirs should end with /
  9.         url = m_ftpOptionsStr[CURLOPT_URL]+path+"/";
  10.     }
  11.     else
  12.     {
  13.         url = m_ftpOptionsStr[CURLOPT_URL]+path;
  14.     }
  15.  
  16.     const char* urlCstr = url.c_str();
  17.  
  18.     CURL* handle = curl_easy_init();
  19.     SetHandleOptions(handle);
  20.     curl_easy_setopt(handle, CURLOPT_URL, urlCstr);
  21.     curl_easy_setopt(handle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_MULTICWD);
  22.     curl_easy_setopt(handle, CURLOPT_FTP_CREATE_MISSING_DIRS, CURLFTP_CREATE_DIR);
  23.  
  24.     FileReader* reader = new FileReader();
  25.     reader->SetUploader(this);
  26.  
  27.     if(isFile)
  28.     {
  29.         struct stat file_info;
  30.         FILE *fd;
  31.  
  32.         //open file and read it
  33.         const char* fileCstr = localpath.c_str();
  34.         fd = fopen(fileCstr, "rb"); /* open file to upload */
  35.         if(!fd)
  36.         {
  37.             /* can't continue */
  38.             SendMessage(_("Cannot Open File\n %s\nUpload Terminated!")+localpath);
  39.             return ;
  40.         }
  41.  
  42.         /* to get the file size */
  43.         if(fstat(fileno(fd), &file_info) != 0)
  44.         {
  45.             /* can't continue */
  46.             SendMessage(_("Cannot Get File size\n %s\nUpload Terminated!")+localpath);
  47.             return ;
  48.         }
  49.  
  50.         //set file to read
  51.         reader->SetFile(fd);
  52.  
  53.         //save handle in vector
  54.         m_fileHandles.push_back(reader);
  55.  
  56.         //do file upload here
  57.         curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
  58.         /* and give the size of the upload (optional) */
  59.         curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
  60.         /* set where to read from (on Windows you need to use READFUNCTION too) */
  61.         curl_easy_setopt(handle, CURLOPT_READFUNCTION, Uploader::ReadCallback);
  62.         curl_easy_setopt(handle, CURLOPT_READDATA, (void*)reader);
  63.  
  64.     }
  65.     else
  66.     {
  67.         //its dir, just run MKD indirectly via CWD
  68.         curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, Uploader::WriteDataCallBack);
  69.         curl_easy_setopt(handle, CURLOPT_WRITEDATA, reader);
  70.     }
  71.     //Queue it to multi handle
  72.     curl_multi_add_handle(m_curlMultiHandle, handle);
  73. }
  74.  
  75. void Uploader::UploadQueue()
  76. {
  77.     int still_running;
  78.  
  79.     CURLMsg* msg; /* for picking up messages with the transfer status */
  80.     int msgs_left; /* how many messages are left */
  81.  
  82.     /* we start some action by calling perform right away */
  83.     curl_multi_perform(m_curlMultiHandle, &still_running);
  84.  
  85.     do
  86.     {
  87.         struct timeval timeout;
  88.         int rc; /* select() return code */
  89.  
  90.         fd_set fdread;
  91.         fd_set fdwrite;
  92.         fd_set fdexcep;
  93.         int maxfd = -1;
  94.  
  95.         long curl_timeo = -1;
  96.  
  97.         FD_ZERO(&fdread);
  98.         FD_ZERO(&fdwrite);
  99.         FD_ZERO(&fdexcep);
  100.  
  101.         /* set a suitable timeout to play around with */
  102.         timeout.tv_sec = 1;
  103.         timeout.tv_usec = 0;
  104.  
  105.         curl_multi_timeout(m_curlMultiHandle, &curl_timeo);
  106.         if(curl_timeo >= 0)
  107.         {
  108.             timeout.tv_sec = curl_timeo / 1000;
  109.             if(timeout.tv_sec > 1)
  110.                 timeout.tv_sec = 1;
  111.             else
  112.                 timeout.tv_usec = (curl_timeo % 1000) * 1000;
  113.         }
  114.  
  115.         /* get file descriptors from the transfers */
  116.         curl_multi_fdset(m_curlMultiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
  117.  
  118.         /* In a real-world program you OF COURSE check the return code of the
  119.            function calls.  On success, the value of maxfd is guaranteed to be
  120.            greater or equal than -1.  We call select(maxfd + 1, ...), specially in
  121.            case of (maxfd == -1), we call select(0, ...), which is basically equal
  122.            to sleep. */
  123.  
  124.         rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
  125.  
  126.         switch(rc)
  127.         {
  128.             case -1:
  129.                 /* select error */
  130.                 break;
  131.             case 0:
  132.             default:
  133.                 /* timeout or readable/writable sockets */
  134.                 curl_multi_perform(m_curlMultiHandle, &still_running);
  135.                 break;
  136.         }
  137.     }
  138.     while(still_running);
  139.  
  140.     curl_multi_cleanup(m_curlMultiHandle);
  141.  
  142.     /* See how the transfers went */
  143.     while ((msg = curl_multi_info_read(m_curlMultiHandle, &msgs_left)))
  144.     {
  145.         if (msg->msg == CURLMSG_DONE)
  146.         {
  147.             SendMessage(wxString::Format(_("FTP transfer completed with status: %d: %s"), (int)msg->data.result, curl_easy_strerror(msg->data.result)));
  148.             curl_easy_cleanup(msg->easy_handle);
  149.         }
  150.     }
  151.  
  152.     //clean files and all other stuffs
  153.     for(int i=0; i<m_fileHandles.size(); i++)
  154.     {
  155.         fclose(m_fileHandles.at(i)->GetFile());
  156.         delete m_fileHandles.at(i);
  157.     }
  158.     //clear the data structures
  159.     m_fileHandles.clear();
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement