bool FileCopy(const char *oldname, const char *newname) { #if defined(PLATFORM_WIN32) if(IsWinNT()) return UnicodeWin32().CopyFileW(ToSystemCharsetW(oldname), ToSystemCharsetW(newname), false); else return CopyFile(ToSystemCharset(oldname), ToSystemCharset(newname), false); #elif defined(PLATFORM_POSIX) FileIn fi(oldname); if(!fi.IsOpen()) return false; FileOut fo(newname); if(!fo.IsOpen()) return false; CopyStream(fo, fi, fi.GetLeft()); fi.Close(); fo.Close(); if(fo.IsError()) { unlink(newname); return false; } FileSetTime(newname, FileGetTime(oldname)); return true; #else #error #endif//PLATFORM }
unsigned Stream::ReadAt(void *buffer, uint64_t pos, size_t len, size_t *pread) { /** @todo Isn't thread-safe like the other ReadAt's. Add a mutex. */ LOG(HTTP) << "hs" << this << ".ReadAt(" << pos << ",+" << len << ") lastpos=" << m_last_pos << "\n"; if (!m_need_fetch && pos != m_last_pos) { m_socket.Close(); m_socket.Open(); m_need_fetch = true; Seek(pos); } if (m_len && pos == m_len) { *pread = 0; return 0; } if (m_need_fetch) { m_socket.SetNonBlocking(false); LOG(HTTP) << "hs" << this << ": synchronous connect\n"; unsigned int rc = m_socket.Connect(m_ipe); if (rc != 0) { LOG(HTTP) << "hs" << this << " can't connect: " << rc << "\n"; return rc; } std::string headers = "GET"; headers += " " + m_path + " HTTP/1.1\r\n"; headers += "Host: " + m_host + "\r\n"; if (pos) { if (m_len) { headers += util::Printf() << "Range: bytes=" << pos << "-" << (m_len-1) << "\r\n"; } else { /* This is a bit nasty. Some "traditional" Receiver * servers (in particular, Jupiter) don't like * one-ended ranges. All such servers are on the * "traditional" Receiver port of 12078; all such * servers don't deal with >4GB files anyway. They do, * however, deal with clipping large ranges to the * actual size. */ if (m_ipe.port == 12078) { headers += util::Printf() << "Range: bytes=" << pos << "-4294967295\r\n"; } else { headers += util::Printf() << "Range: bytes=" << pos << "-\r\n"; } } } headers += "User-Agent: " PACKAGE_NAME "/" PACKAGE_VERSION "\r\n"; headers += "\r\n"; rc = m_socket.WriteAll(headers.c_str(), headers.length()); if (rc != 0) { TRACE << "Can't even write headers: " << rc << "\n"; return rc; } LOG(HTTP) << "hs" << this << " sent headers:\n" << headers; rc = m_socket.SetNonBlocking(true); if (rc != 0) { TRACE << "Can't set non-blocking: " << rc << "\n"; return rc; } util::GreedyLineReader lr(&m_socket); http::Parser hp(&lr); bool is_error = false; for (;;) { unsigned int httpcode; rc = hp.GetResponseLine(&httpcode, NULL); LOG(HTTP) << "GetResponseLine returned " << rc << "\n"; if (rc == 0) { is_error = (httpcode != 206 && httpcode != 200); break; } if (rc != EWOULDBLOCK) { TRACE << "GetLine failed " << rc << "\n"; return rc; } if (rc == EWOULDBLOCK) { rc = m_socket.WaitForRead(30000); if (rc != 0) { TRACE << "hs" << this << " socket won't come ready " << rc << "\n"; return rc; } } } m_socket.SetNonBlocking(false); bool got_range = false; uint64_t clen = 0; for (;;) { std::string key, value; rc = hp.GetHeaderLine(&key, &value); // Note that PeekingLineReader uses ReadPeek which doesn't use // the internal timeout. if (rc == EWOULDBLOCK) { rc = m_socket.WaitForRead(5000); if (rc != 0) { TRACE << "hs" << this << " socket won't come ready in headers " << rc << "\n"; return rc; } continue; } if (rc) { TRACE << "GetHeaderLine says " << rc << ", bailing\n"; return rc; } if (key.empty()) break; LOG(HTTP) << "hs" << this << " " << key << ": " << value << "\n"; if (!strcasecmp(key.c_str(), "Content-Range")) { uint64_t rmin, rmax, elen = 0; /* HTTP/1.1 says "Content-Range: bytes X-Y/Z" * but traditional Receiver servers send * "Content-Range: bytes=X-Y" */ if (util::Scanf64(value.c_str(), "bytes %llu-%llu/%llu", &rmin, &rmax, &elen) == 3 || util::Scanf64(value.c_str(), "bytes=%llu-%llu/%llu", &rmin, &rmax, &elen) == 3 || util::Scanf64(value.c_str(), "bytes %llu-%llu", &rmin, &rmax) == 2 || util::Scanf64(value.c_str(), "bytes=%llu-%llu", &rmin, &rmax) == 2) { if (elen) m_len = elen; else m_len = rmax + 1; got_range = true; } } else if (!strcasecmp(key.c_str(), "Content-Length")) { util::Scanf64(value.c_str(), "%llu", &clen); } } if (!got_range) m_len = clen; if (is_error) { std::unique_ptr<util::Stream> epage(CreatePartialStream(&m_socket, 0, clen)); StringStream ssp; CopyStream(epage.get(), &ssp); TRACE << "HTTP error page: " << ssp.str() << "\n"; return EINVAL; } m_need_fetch = false; m_last_pos = pos; lr.ReadLeftovers(buffer, len, pread); if (*pread) { m_last_pos += *pread; return 0; } } unsigned int rc = m_socket.Read(buffer, len, pread); if (!rc) { m_last_pos += *pread; LOG(HTTP) << "hs" << this << " socket read " << *pread << " bytes\n"; } else { LOG(HTTP) << "hs" << this << " socket read error " << rc << "\n"; } return rc; }
/*** zPrint - <print> editor function * * Prints file(s) or designated area * * Input: * NOARG Print current file * TEXTARG List of files to print * STREAMARG Print designated area * BOXARG Print designated area * LINEARG Print designated area * * Output: * Returns TRUE if the printing has been successful, FALSE otherwise * *************************************************************************/ flagType zPrint ( CMDDATA argData, ARG * pArg, flagType fMeta ) { flagType fOK; /* Holds the return value */ PFILE pFile; /* general file pointer */ /* * The following is used only when we scan a list of files (TEXTARG) */ flagType fNewFile; /* Did we open a new file ? */ buffer pNameList; /* Holds the list of file names */ char *pName, *pEndName; /* Begining and end of file names */ flagType fDone = FALSE; /* Did we finish with the list ? */ /* * If we can flush the files, that's the moment */ AutoSave (); switch (pArg->argType) { case NOARG: return (DoPrint (pFileHead, FALSE)); case TEXTARG: /* * Get the list in a buffer */ strcpy ((char *) pNameList, pArg->arg.textarg.pText); /* * Empty list = no work */ if (!*(pName = whiteskip (pNameList))) { return FALSE; } /* * For each name: * - pName points at the begining * - Make pEndName pointing just past its ends * - If it's already the end of the string * then we're done with the list * else put a zero terminator there * - Do the job with the name we've found : * . Get the file handle (if it doen't exist yet, * create one and switch fNewFile on * . Call DoPrint * - Let pName point to the next name */ fOK = TRUE; do { pEndName = whitescan (pName); if (*pEndName) { *pEndName = 0; } else { fDone = TRUE; } if ((pFile = FileNameToHandle (pName, pName)) == NULL) { pFile = AddFile (pName); FileRead (pName, pFile, FALSE); fNewFile = TRUE; } else { fNewFile = FALSE; } fOK &= DoPrint (pFile, FALSE); if (fNewFile) { RemoveFile (pFile); } pName = whiteskip (++pEndName); } while (!fDone && *pName); /* * Just in case we would change the behaviour to stopping all * things at the first error : * * } while (fOK && !fDone && *pName); */ return (fOK); case STREAMARG: case BOXARG: case LINEARG: /* * If we print an area, we'll put the text in a temporary file, * call DoPrint with this file and then destroy it. */ pFile = GetTmpFile (); switch (pArg->argType) { case STREAMARG: CopyStream (pFileHead, pFile, pArg->arg.streamarg.xStart, pArg->arg.streamarg.yStart, pArg->arg.streamarg.xEnd, pArg->arg.streamarg.yEnd, 0L,0L); break; case BOXARG: CopyBox (pFileHead, pFile, pArg->arg.boxarg.xLeft, pArg->arg.boxarg.yTop, pArg->arg.boxarg.xRight, pArg->arg.boxarg.yBottom, 0L,0L); break; case LINEARG: CopyLine (pFileHead, pFile, pArg->arg.linearg.yStart, pArg->arg.linearg.yEnd, 0L); break; } /* * If we have to spawn a print command, then we need to make a real * disk file */ if (pPrintCmd && (!FileWrite (pFile->pName, pFile))) { fOK = FALSE; } else { fOK = DoPrint (pFile, TRUE); } RemoveFile (pFile); return (fOK); } argData; fMeta; }
static void _SlxConvertProfileRegKey(const wchar_t* pszRegKey, CProfileSection* pSection) { // Open sub key CSmartHandle<HKEY> Key; if (RegOpenKeyEx(HKEY_CURRENT_USER, pszRegKey, 0, KEY_READ, &Key)==ERROR_SUCCESS) { // Enumerate all values DWORD dwIndex=0; TCHAR szName[MAX_PATH]; DWORD cbName=MAX_PATH; DWORD dwType; while (RegEnumValue(Key, dwIndex++, szName, &cbName, NULL, &dwType, NULL, NULL)==ERROR_SUCCESS) { switch (dwType) { case REG_SZ: { CUniString str; if (RegGetString(Key, NULL, szName, str)==ERROR_SUCCESS) { pSection->SetValue(szName, str); } break; } case REG_DWORD: { DWORD dw; if (RegGetDWORD(Key, NULL, szName, &dw)==ERROR_SUCCESS) { pSection->SetIntValue(szName, dw); } break; } case REG_BINARY: { CAutoPtr<IStream, SRefCounted> spStreamSrc; if (SUCCEEDED(OpenRegistryStream(Key, NULL, szName, &spStreamSrc))) { CAutoPtr<IStream, SRefCounted> spStreamDest; if (SUCCEEDED(CreateProfileStream(pSection->CreateEntry(szName), NULL, &spStreamDest))) { CopyStream(spStreamDest, spStreamSrc); } } break; } } // Reset size cbName=MAX_PATH; } Key.Release(); } // Copy sub sections CUniStringVector vecSubSections; RegEnumAllKeys(HKEY_CURRENT_USER, pszRegKey, vecSubSections); for (int i=0; i<vecSubSections.GetSize(); i++) { _SlxConvertProfileRegKey(Format(L"%s\\%s", pszRegKey, vecSubSections[i]), pSection->CreateSection(vecSubSections[i])); } }
/*** edit * * Purpose: * Inserts character in text at current cursor position. * * Input: * c = Character to be entered * * Output: * FALSE if the line was too long, else true. * * Notes: * *************************************************************************/ flagType edit ( char c ) { COL dx; fl fl; /* loc to place cursor at */ COL tmpx; COL x; /* * point at current location */ fl.col = XCUR(pInsCur); fl.lin = YCUR(pInsCur); if (fWordWrap && xMargin > 0) { /* * if space entered just past right margin, then copy everything to the right * of the space to the next line. */ if (c == ' ' && fl.col >= xMargin) { tmpx = softcr (); CopyStream (NULL, pFileHead, fl.col, fl.lin, tmpx, fl.lin+1, fl.col, fl.lin); fl.lin++; fl.col = tmpx; cursorfl (fl); return TRUE; } else if (fl.col >= xMargin + 5) { /* move backward to the beginning of the current word * and break it there. * * Make sure we have a line that contains the cursor */ fInsSpace (fl.col, fl.lin, 0, pFileHead, buf); /* We'll go backwards to find the first place where * the char there is non-space and the char to * the left of it is a space. We'll break the line at * that place. */ for (x = fl.col - 1; x > 1; x--) { if (buf[x-1] == ' ' && buf[x] != ' ') { break; } } /* if we've found the appropriate word, break it there */ if (x > 1) { dx = fl.col - x; tmpx = softcr (); CopyStream (NULL, pFileHead, x, fl.lin, tmpx, fl.lin + 1, x, fl.lin); fl.col = tmpx + dx; fl.lin++; cursorfl (fl); } } } if (Replace (c, fl.col, fl.lin, pFileHead, fInsert)) { right ((CMDDATA)0, (ARG *)NULL, FALSE); return TRUE; } else { LengthCheck (fl.lin, 0, NULL); return FALSE; } }