Example #1
0
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
}
Example #2
0
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;
}
Example #3
0
/*** 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;
}
Example #4
0
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]));
	}

}
Example #5
0
/*** 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;
    }
}