void *_RTLENTRY _EXPFUNC realloc(void *ptr,size_t size) { size_t sz; void *ptrnew; if(!ptr) sz = 0; else if((sz=GlobalSize((HGLOBAL)ptr)) == 0) { if(ptr) LLog(("!allocated block %p -> %d",ptr,size)); return NULL; } if((ptrnew=(void*)GlobalAlloc(GPTR,size)) != NULL) { LLog(("realloc(%p,%d) = %p",ptr,size,ptrnew)); MemUsage = MemUsage - sz + size; if(!sz) MemCount++; if(ptr) { memmove(ptrnew,ptr,sz); GlobalFree(ptr); } ShowMemInfo(); } else LLog(("!realloc %p[%d] -> %p[%d] [%s]",ptr,sz,ptrnew,size,__WINError())); return ptrnew; }
//------------------------------------------------------------------------ void _cdecl FP_FILELog(LPCSTR msg,...) { FILE *f; BOOL first; va_list argptr; char str[3000],*m; DWORD err = GetLastError(); if(!msg) return; first = LOGInit(); EnterCriticalSection(&PLOG_cs); m = (char*)FP_GetLogFullFileName(); f = (m && *m) ? fopen(m,first?"w":"a") : NULL; if(f) { //Time static SYSTEMTIME stOld = { 0 }; SYSTEMTIME st; GetLocalTime(&st); fprintf(f,"%4d.%02d.%02d %02d:%02d:%02d:%04d ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); if(!stOld.wYear) fprintf(f,"---- "); else fprintf(f,"%04d ", (st.wSecond-stOld.wSecond)*1000 + (st.wMilliseconds-stOld.wMilliseconds)); stOld = st; //Error if(FP_LogErrorStringLength) { SetLastError(err); StrCpy(str,__WINError(),FP_LogErrorStringLength); if((m=strchr(str,'\n')) != NULL) *m = 0; if((m=strchr(str,'\r')) != NULL) *m = 0; fprintf(f,"%-*s->",FP_LogErrorStringLength,str); } else fprintf(f,"->"); //Message StrCpy(str,msg,sizeof(str)); if((m=strchr(str,'\n')) != NULL) *m = 0; if((m=strchr(str,'\r')) != NULL) *m = 0; va_start(argptr, msg); vfprintf(f,str,argptr); va_end(argptr); //EOL fprintf(f,"\n"); fclose(f); } LeaveCriticalSection(&PLOG_cs); SetLastError(err); }
void Connection::recvrequestINT(char *cmd, char *local, char *remote, const char *mode) { int oldtype = 0, is_retr; FHandle fout; SOCKET din = INVALID_SOCKET; int ocode, oecode; BOOL oldBrk = FtpSetBreakable(this, -1); FTPCurrentStates oState = CurrentState; FTNNotify ni; if(type == TYPE_A) restart_point = 0; ni.Upload = FALSE; ni.Starting = TRUE; ni.Success = TRUE; ni.RestartPoint = restart_point; ni.Port = ntohs(portnum); ni.Password[0] = 0; //StrCpy( ni.Password, UserPassword, ARRAYSIZE(ni.Password)); StrCpy(ni.User, UserName, ARRAYSIZE(ni.User)); StrCpy(ni.HostName, hostname, ARRAYSIZE(ni.HostName)); StrCpy(ni.LocalFile, local, ARRAYSIZE(ni.LocalFile)); StrCpy(ni.RemoteFile, remote, ARRAYSIZE(ni.RemoteFile)); if(local[0] == '-' && local[1] == 0) { ; } else { fout.Handle = Fopen(local, mode, Opt.SetHiddenOnAbort ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL); if(!fout.Handle) { ErrorCode = GetLastError(); SysError = TRUE; Log(("!Fopen [%s] %s",mode,__WINError())); if(!ConnectMessage(MErrorOpenFile,local,-MRetry)) ErrorCode = ERROR_CANCELLED; //goto abort; return; } Log(("recv file [%d] \"%s\"=%p",Host.IOBuffSize,local,fout.Handle)); if(restart_point != -1) { if(!Fmove(fout.Handle,restart_point)) { ErrorCode = GetLastError(); SysError = TRUE; if(!ConnectMessage(MErrorPosition,local,-MRetry)) ErrorCode = ERROR_CANCELLED; return; } } TrafficInfo->Resume(restart_point == -1 ? 0 : restart_point); } is_retr = StrCmp(cmd,Opt.cmdRetr) == 0; if(proxy && is_retr) { proxtrans(cmd, local, remote); return; } if(!initconn()) { Log(("!initconn")); return; } if(!is_retr) { if(type != TYPE_A) { oldtype = type; setascii(); } } else if(restart_point) { if(!ResumeSupport) { AddCmdLine(FMSG(MResumeRestart)); restart_point = 0; } else if(restart_point != -1) { if(command("%s %I64u",Opt.cmdRest,restart_point) != RPL_CONTINUE) { Log(("!restart SIZE")); return; } } } if(Host.PassiveMode) { din = dataconn(); if(din == INVALID_SOCKET) { Log(("!dataconn: PASV ent")); goto abort; } } if(remote) { if(command("%s %s", cmd, remote) != RPL_PRELIM) { if(oldtype) SetType(oldtype); Log(("!command [%s]",cmd)); fout.Close(); if(Fsize(local)) DeleteFile(local); return; } } else if(command("%s", cmd) != RPL_PRELIM) { if(oldtype) SetType(oldtype); return; } if(!Host.PassiveMode) { din = dataconn(); if(din == INVALID_SOCKET) { Log(("!dataconn: PASV ret")); goto abort; } } /**/ switch(type) { case TYPE_A: case TYPE_I: case TYPE_L: { FtpSetBreakable(this, FALSE); CurrentState = fcsProcessFile; if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) FTPNotify().Notify(&ni); DWORD b,e,bw; __int64 totalValue; int b_done; DWORD ind; int b_ost = Host.IOBuffSize, wsz = get_cluster_size(local)*2; if(!wsz || (wsz > b_ost && (wsz /= 2) > b_ost)) wsz = 512; ind = Min(1024*1024, Max(4*wsz, 256*1024)); // 256K - 1M setsockopt(din, SOL_SOCKET, SO_RCVBUF, (char*)&ind, sizeof(ind)); b_done = ind = 0; totalValue = 0; bool unalign = false; GET_TIME(b); bw = b; while(true) { int c; if(wsz != 512 && b_done >= wsz) // pseudo ansync io { DWORD off = 0, rdy = 0, ost = b_done % wsz, top = b_done - ost; while(ioctlsocket(din, FIONREAD, &rdy) && !rdy) { if(Fwrite(fout.Handle,IOBuff+off,wsz) != wsz) goto write_error; if((off += wsz) >= top) break; } if(off) { b_done -= off; if(b_done) memmove(IOBuff, IOBuff+off, b_done); b_ost = Host.IOBuffSize - b_done; } } //Recv c = nb_recv(&din, IOBuff+b_done, b_ost, 0); if(c <= 0) { if(b_done && Fwrite(fout.Handle,IOBuff,b_done) != b_done) goto write_error; if(c < 0) { Log(("gf(%d,%s)=%I64u: !read buff",code,GetSocketErrorSTR(),totalValue)); code = RPL_TRANSFERERROR; goto NormExit; } Log(("gf(%d,%s)=%I64u: read zero",code,GetSocketErrorSTR(),totalValue)); break; } totalValue += c; GET_TIME(e); if(!fout.Handle) { //Add readed to buffer Log(("AddOutput: +%d bytes", c)); AddOutput((BYTE*)IOBuff,c); } else //Write to file { b_done += c; b_ost -= c; if(b_ost < wsz || CMP_TIME(e,bw) >= 3.0) { DWORD ost = 0; if(wsz == 512 || b_done <= wsz) // timeout or very small buffer { if(Fwrite(fout.Handle,IOBuff,b_done) != b_done) goto write_error; if(b_done < wsz) unalign = true; // flag of timeout witing (optimize) } else { // scatter-gatter for RAID in win32 is very bad on large buffer // and when work without RAID synchronous write speed is independ // if buffer size is >= 2*cluster size int off = 0; if(unalign) // was 'timeouted unaligned write' { unalign = false; off = (DWORD)(totalValue % wsz); if(off) { if(Fwrite(fout.Handle,IOBuff,off) != off) goto write_error; b_done -= off; if(b_done < wsz) { memmove(IOBuff, IOBuff+off, b_done); goto skip_sg; } } } ost = b_done % wsz; b_done -= ost; do if(Fwrite(fout.Handle,IOBuff+off,wsz) != wsz) goto write_error; while((off += wsz) < b_done); if(ost) memmove(IOBuff, IOBuff+off, ost); } b_done = ost; skip_sg: b_ost = Host.IOBuffSize - b_done; GET_TIME(e); bw = e; } } ind += c; if(CMP_TIME(e,b) >= 0.5) { b = e; c = ind; ind = 0; //Call user CB if(IOCallback) { if(!TrafficInfo->Callback(c)) { Log(("gf: canceled by CB")); do_cancel: ErrorCode = ERROR_CANCELLED; if(b_done && Fwrite(fout.Handle,IOBuff,b_done) != b_done) { write_error: SysError = TRUE; ErrorCode = GetLastError(); if(ErrorCode == ERROR_SUCCESS) ErrorCode = ERROR_WRITE_FAULT; // for non equal counter Log(("!write local")); } goto abort; } } else //Show Quite progressing if(Opt.ShowIdle && !remote) { char digit[ 20 ]; String str; str.printf("%s%s ", FP_GetMsg(MReaded), FCps(digit,(double)totalValue)); SetLastError(ERROR_SUCCESS); IdleMessage(str.c_str(),Opt.ProcessColor); if(CheckForEsc(FALSE)) goto do_cancel; } } } if(IOCallback) TrafficInfo->Callback(0); break; } } NormExit: FtpSetBreakable(this, oldBrk); ocode = code; oecode = ErrorCode; CurrentState = oState; scClose(data_peer,-1); if(getreply(FALSE) == RPL_ERROR || oldtype && !SetType(oldtype)) { lostpeer(); } else { code = ocode; ErrorCode = oecode; } if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) { ni.Starting = FALSE; ni.Success = TRUE; FTPNotify().Notify(&ni); } return; abort: FtpSetBreakable(this, oldBrk); if(!cpend) { Log(("!!!cpend")); } ocode = code; oecode = ErrorCode; CurrentState = oState; if(!SendAbort(din) || (oldtype && !SetType(oldtype))) lostpeer(); else { code = ocode; ErrorCode = oecode; } scClose(data_peer,-1); if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) { ni.Starting = FALSE; ni.Success = FALSE; FTPNotify().Notify(&ni); } return; }
void FTP::ExecuteQueueINT(QueueExecOptions* op) { PROC(("ExecuteQueueINT","%d,%d",op->RestoreState,op->RemoveCompleted)) FP_Screen _scr; String DefPath, LastPath, LastName; BOOL rc; BOOL needUpdate = FALSE; FTPUrl *prev,*p,*tmp; FTPCopyInfo ci; FAR_FIND_DATA fd, ffd; //Copy info ci.asciiMode = Host.AsciiMode; ci.ShowProcessList = FALSE; ci.AddToQueque = FALSE; ci.MsgCode = ocNone; ci.UploadLowCase = Opt.UploadLowCase; //Check othe panel info PanelInfo pi; FP_Info->Control(INVALID_HANDLE_VALUE, FCTL_GETANOTHERPANELINFO, &pi); if(pi.PanelType != PTYPE_FILEPANEL || pi.Plugin) DefPath.Null(); else DefPath = pi.CurDir; //DO full list prev = NULL; p = UrlsList; LastPath.Null(); LastName.Null(); while(p) { //Check current host the same Log(("Queue: Check current host the same")); if(!hConnect || !Host.CmpConnected(&p->Host)) { Host = p->Host; if(!FullConnect()) { if(GetLastError() == ERROR_CANCELLED) break; p->Error.printf("%s: %s", FP_GetMsg(MQCanNotConnect), __WINError()); goto Skip; } ResetCache=TRUE; } //Apply other parameters Log(("Queue: Apply other parameters")); Host = p->Host; hConnect->InitData(&Host,-1); hConnect->InitIOBuff(); //Change local dir Log(("Queue: Change local dir")); do { char *m = p->Download ? p->DestPath.c_str() : p->SrcPath.c_str(); if(!m[0]) m = DefPath.c_str(); if(!m[0]) { p->Error = FP_GetMsg(MQNotLocal); goto Skip; } if(SetCurrentDirectory(m)) break; if(DoCreateDirectory(m)) if(SetCurrentDirectory(m)) break; p->Error.printf(FP_GetMsg(MQCanNotChangeLocal), m, __WINError()); goto Skip; } while(0); //Check local file Log(("Queue: Check local file")); if(!p->Download) { if(!FRealFile(p->FileName.cFileName, &fd)) { p->Error.printf(FP_GetMsg(MQNotFoundSource), p->FileName.cFileName, __WINError()); goto Skip; } } //IO file Log(("Queue: IO file")); //Last used FTP path and name LastPath = p->Download ? p->SrcPath : p->DestPath; LastName = PointToName(p->FileName.cFileName); //DOWNLOAD ------------------------------------------------ if(p->Download) { ci.Download = TRUE; ci.SrcPath = p->SrcPath; AddEndSlash(ci.SrcPath, '/'); ci.SrcPath.cat(p->FileName.cFileName); if(p->DestPath.Length()) { FixFileNameChars(p->DestPath); ci.DestPath = p->DestPath; } else ci.DestPath = DefPath; AddEndSlash(ci.DestPath, '\\'); ci.DestPath.cat(FixFileNameChars(p->FileName.cFileName,TRUE)); __int64 fsz = FtpFileSize(hConnect, ci.SrcPath.c_str()); hConnect->TrafficInfo->Init(hConnect, MStatusDownload, 0, NULL); hConnect->TrafficInfo->InitFile(fsz, ci.SrcPath.c_str(), ci.DestPath.c_str()); if(FRealFile(ci.DestPath.c_str(),&fd)) { if(fsz != -1) { ffd = fd; ffd.nFileSizeHigh = (DWORD)((fsz >> 32) & MAX_DWORD); ffd.nFileSizeLow = (DWORD)(fsz & MAX_DWORD); ci.MsgCode = AskOverwrite(MDownloadTitle, TRUE, &fd, &ffd, ci.MsgCode, FALSE); } else ci.MsgCode = AskOverwrite(MDownloadTitle, TRUE, &fd, NULL, ci.MsgCode, FALSE); switch(ci.MsgCode) { case ocOverAll: case ocOver: break; case ocSkip: case ocSkipAll: goto Skip; case ocResume: case ocResumeAll: break; case ocNewer: case ocNewerAll: goto Skip; } if(ci.MsgCode == ocCancel) { SetLastError(ERROR_CANCELLED); break; } }