📄 ftpcli.cpp
字号:
int Tos = IPTOS_THROUGHPUT; FILE * fp = NULL; float Per; int DataSock = DataSkp->GetSockfd(); Length = This->RemoteEndPos - This->RemoteStartPos; if (!(fp = fopen(This->LocalFile, This->FileMode))) { Disconnect(); close(DataSock); This->Status = LOCALFATAL; return FOPENERR; } setsockopt(DataSock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos)); setvbuf(fp, NULL, _IONBF, 0); This->Status = DOWNLOADING; while(Length > 0) { if(Length < FTP_BUF_SIZE && Length > 0) { while(Length > 0) { BytesRead = ReadMsg(DataSock, szBuffer, Length); if (BytesRead == -1) { ShowMsg("error receving data"); fclose(fp); Disconnect(); close(DataSock); if(errno == ETIMEDOUT) { ShowMsg("TThread timed out"); This->Status = TIMEDOUT; return READERR; } This->Status = REMOTEFATAL; return READERR; } if (BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp)) { ShowMsg("write failed"); fclose(fp); Disconnect(); close(DataSock); This->Status = LOCALFATAL; return FWRITEERR; } Length -= BytesRead; Total += BytesRead; This->RemoteBytesReceived += BytesRead;#ifdef DEBUG Per = This->RemoteBytesReceived * 100 / This->BlkSize; ShowMsg("%s has finished %.1f%%", This->Name, Per);#endif#ifdef USE_QT// This->Task->DoInterface();#endif } break; } BytesRead = ReadMsg(DataSock, szBuffer, FTP_BUF_SIZE); if(BytesRead == -1) { ShowMsg("error receving data"); fclose(fp); Disconnect(); close(DataSock); if (errno == ETIMEDOUT) { ShowMsg("TThread timed out"); This->Status = TIMEDOUT; return READERR; } This->Status = REMOTEFATAL; return READERR; } if(BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp)) { ShowMsg("write failed"); fclose(fp); Disconnect(); close(DataSock); This->Status = LOCALFATAL; return FWRITEERR; } Length -= BytesRead; Total += BytesRead; This->RemoteBytesReceived += BytesRead;#ifdef DEBUG Per = This->RemoteBytesReceived * 100 / This->BlkSize; ShowMsg("%s has finished %.1f%%", This->Name, Per);#endif#ifdef USE_QT // This->Task->DoInterface();#endif } fclose(fp); This->Status = ALLDONE; Disconnect(); close(DataSock); ShowMsg("download for this thread completed"); ShowMsg("%s : %ld received", This->LocalFile, Total); return FTPOK;}uerr_t TFtpCli ::RetrFileUnknownSize(TThread * This){ long BytesRead; FILE * fp = NULL; char szBuffer[FTP_BUF_SIZE]; int Tos = IPTOS_THROUGHPUT; int DataSock = DataSkp->GetSockfd(); if (!(fp = fopen(This->LocalFile, This->FileMode))) { Disconnect(); close(DataSock); This->Status = LOCALFATAL; return FOPENERR; } setsockopt(DataSock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos)); setvbuf(fp, NULL, _IONBF, 0); This->Status = DOWNLOADING; do { BytesRead = Recv(DataSock, szBuffer, FTP_BUF_SIZE, 0); if (BytesRead > 0) { if (fwrite(szBuffer, sizeof(char), BytesRead, fp) < BytesRead) { fclose(fp); Disconnect(); close(DataSock); ShowMsg("write failed"); This->Status = LOCALFATAL; return FWRITEERR; } This->RemoteBytesReceived += BytesRead; } }while (BytesRead > 0); fclose(fp); if (BytesRead == -1) { if (errno == ETIMEDOUT) { ShowMsg("TThread timed out"); This->Status = TIMEDOUT; return READERR; } This->Status = REMOTEFATAL; return READERR; } This->Status = ALLDONE; Disconnect(); close(DataSock); return FTPOK;}uerr_t TFtpCli :: GetFileChunk(TThread * This){ uerr_t err; FILE *fp = NULL; unsigned char PasvAddr[6]; int DataSock; int CtrlSock; /* * set the thread attributes */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); if (This->Status == ALLDONE) { gettimeofday(&This->BeginTime, NULL); return FTPOK; } This->Task->LockThread(This->Task); This->Status = CONNECTING; This->Task->BroadcastCond(This->Task); This->Task->UnlockThread(This->Task); err = Connect(); if (err != FTPOK) { if (err == FTPCONREFUSED) { Disconnect(); This->Status = CONREJECT; return err; } else { ShowMsg("Error connecting to %s", This->u->HostName); This->Status = REMOTEFATAL; return err; } } ShowMsg("Connect Ok"); CtrlSock = CtrlSkp->GetSockfd(); if(UserName == NULL) UserName = DEFAULT_FTP_USER; if(PassWord == NULL) PassWord = DEFAULT_FTP_PASSWD; ShowMsg("Logging in as user %s password %s", UserName, PassWord); This->Status = LOGGININ; err = Login(); if (err != FTPOK) { if (err == FTPLOGREFUSED) { Disconnect(); This->Status = LOGINFAIL; return err; } else { ShowMsg("Login Failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } } ShowMsg("Login Ok"); if(IsBinary) { err = Binary(); if (err != FTPOK) { ShowMsg("Binary Failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("Binary OK"); } if (HostDirName) { err = Cwd(HostDirName); if (err != FTPOK) { ShowMsg("CWD failed to change to directory %s", HostDirName); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("CWD OK"); } else { ShowMsg("CWD is not needed"); } if(IsPasv == true) { err = Pasv(PasvAddr); if (err == FTPNOPASV || err == FTPINVPASV) { ShowMsg("Server doesn't seem to support PASV"); IsPasv = false; } if (err == FTPOK) { char dhost[256]; unsigned short dport; sprintf(dhost, "%d.%d.%d.%d", PasvAddr[0], PasvAddr[1], PasvAddr[2], PasvAddr[3]); dport = (PasvAddr[4] << 8) + PasvAddr[5]; if(DataSkp != NULL) { close(DataSkp->GetSockfd()); delete DataSkp; } DataSkp = new TSocketCli(dhost); err = DataSkp->Connect(dport); //DataSock = DataSkp->GetSockfd(); if (err != NOCONERROR) { ShowMsg("Error while connecting, \ according to servers PASV info"); close(CtrlSock); This->Status = REMOTEFATAL; return err; } } } if (IsPasv == false) { err = GetListenSocket(); if (err != FTPOK) { ShowMsg("listen failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } } err = Rest(This->RemoteStartPos); if (err != FTPOK) { ShowMsg("REST failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("REST ok"); err = Retr(HostFileName); if (err != FTPOK) { ShowMsg("RETR failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("RETR OK"); if(IsPasv == false) { err = ListenSkp->Accept(&DataSock); if (err != ACCEPTOK) { Disconnect(); This->Status = REMOTEFATAL; return err; } } err = RetrFileKnownSize(This); return err;}uerr_t TFtpCli :: GetFileToEnd(TThread * This){ uerr_t err; unsigned char PasvAddr[6]; int DataSock; int ListenSock; int CtrlSock; /* set the thread attributes */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /* if there is nothing to download then return */ if (This->Status == ALLDONE) { gettimeofday(&This->BeginTime, NULL); return FTPOK; } This->Task->LockThread(This->Task); This->Status = CONNECTING; This->Task->BroadcastCond(This->Task); This->Task->UnlockThread(This->Task); err = Connect(); if (err != FTPOK) { if (err == FTPCONREFUSED) { Disconnect(); This->Status = CONREJECT; return err; } else { ShowMsg("Error connecting to %s", This->u->HostName); This->Status = REMOTEFATAL; return err; } } ShowMsg("Connect Ok"); CtrlSock = CtrlSkp->GetSockfd(); if(UserName == NULL) UserName = DEFAULT_FTP_USER; if(PassWord == NULL) PassWord = DEFAULT_FTP_PASSWD; ShowMsg("Logging in as user %s password %s", UserName, PassWord); This->Status = LOGGININ; err = Login(); if (err != FTPOK) { if (err == FTPLOGREFUSED) { Disconnect(); This->Status = LOGINFAIL; return err; } else { ShowMsg("Login Failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } } ShowMsg("Login Ok"); if(IsBinary) { err = Binary(); if (err != FTPOK) { ShowMsg("Binary Failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("Binary OK"); } if (HostDirName) { err = Cwd(HostDirName); if (err != FTPOK) { ShowMsg("CWD failed to change to directory %s", HostDirName); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("CWD OK"); } ShowMsg("CWD is not needed"); if (IsPasv == true) { err = Pasv(PasvAddr); if (err == FTPNOPASV || err == FTPINVPASV) { ShowMsg("Server doesn't seem to support PASV"); IsPasv = false; } if (err == FTPOK) { char dhost[256]; unsigned short dport; sprintf(dhost, "%d.%d.%d.%d", PasvAddr[0], PasvAddr[1], PasvAddr[2], PasvAddr[3]); dport = (PasvAddr[4] << 8) + PasvAddr[5]; if(DataSkp != NULL) { close(DataSkp->GetSockfd()); delete DataSkp; } DataSkp = new TSocketCli(dhost); err = DataSkp->Connect(dport); //DataSock = DataSkp->GetSockfd(); if (err != NOCONERROR) { ShowMsg("Error while connecting, \ according to servers PASV info"); Disconnect(); This->Status = REMOTEFATAL; return err; } } } if (IsPasv == false) { err = GetListenSocket(); if (err != FTPOK) { ShowMsg("listen failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } } if (This->RemoteStartPos > 0 && This->u->ResumeSupport == true) { err = Rest(This->RemoteStartPos); if (err != FTPOK) { ShowMsg("REST failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } ShowMsg("REST OK"); } err = Retr(HostFileName); if (err != FTPOK) { ShowMsg("RETR failed"); Disconnect(); This->Status = REMOTEFATAL; return err; } if (IsPasv == false) { err = ListenSkp->Accept(&DataSock); if (err != ACCEPTOK) { Disconnect(); This->Status = REMOTEFATAL; return err; } } if(This->u->FileSize == -1) err = RetrFileUnknownSize(This); else err = RetrFileKnownSize(This); return err;}/* * Gets Size about the file from the ftp server */uerr_t TFtpCli :: Size(TUrl * u){ uerr_t err; char szBuffer[FTP_BUF_SIZE]; int CtrlSock = CtrlSkp->GetSockfd(); if (!HostFileName || !(*HostFileName)) { ShowMsg("No file specified."); return FILEBADFILE ; } err = Cwd(HostFileName); if (err == FTPOK) { ShowMsg("you must be specify a FileName"); return FTPOK; } sprintf(szBuffer, "SIZE %s\r\n", HostFileName); err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer)); if (err != FTPOK) return err; err = GetReply(CtrlSock, szBuffer); if (err != FTPOK) return err; if (*szBuffer == '2') { sscanf(szBuffer + 3, "%ld", &u->FileSize); return FTPOK; } else if (*szBuffer == '5') /** A error hapenned */ { if (strstr(szBuffer, "o such file") || strstr(szBuffer, "o Such File") || strstr(szBuffer, "ot found") || strstr(szBuffer, "ot Found")) return FTPNSFOD; }}/*uerr_t TFtpCli :: SearchMirrorSite(TThread * This){}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -