!C99Shell v. 1.0 pre-release build #13!

Software: Apache. PHP/5.5.15 

uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 

SYSTEM 

Safe-mode: OFF (not secure)

C:\dmz\FileZillaFTP\source\   drwxrwxrwx
Free 4.08 GB of 39.52 GB (10.32%)
Detected drives: [ a ] [ c ] [ d ] [ e ] [ f ]
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     Options.cpp (31.81 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// FileZilla Server - a Windows ftp server

// Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// Options.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "options.h"
#include "platform.h"
#include "version.h"
#include "tinyxml/tinyxml.h"
#include "iputils.h"
#include "OptionLimits.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

std::list<COptions *> COptions::m_InstanceList;
CCriticalSectionWrapper COptions::m_Sync;
COptions::t_OptionsCache COptions::m_sOptionsCache[OPTIONS_NUM];
BOOL COptions::m_bInitialized=FALSE;

SPEEDLIMITSLIST COptions::m_sSpeedLimits[2];

/////////////////////////////////////////////////////////////////////////////
// COptionsHelperWindow

class COptionsHelperWindow
{
public:
    COptionsHelperWindow(COptions *pOptions)
    {
        ASSERT(pOptions);
        m_pOptions=pOptions;

        //Create window
        WNDCLASSEX wndclass;
        wndclass.cbSize=sizeof wndclass;
        wndclass.style=0;
        wndclass.lpfnWndProc=WindowProc;
        wndclass.cbClsExtra=0;
        wndclass.cbWndExtra=0;
        wndclass.hInstance=GetModuleHandle(0);
        wndclass.hIcon=0;
        wndclass.hCursor=0;
        wndclass.hbrBackground=0;
        wndclass.lpszMenuName=0;
        wndclass.lpszClassName=_T("COptions Helper Window");
        wndclass.hIconSm=0;

        RegisterClassEx(&wndclass);

        m_hWnd=CreateWindow(_T("COptions Helper Window"), _T("COptions Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
        ASSERT(m_hWnd);
        SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG)this);
    };

    virtual ~COptionsHelperWindow()
    {
        //Destroy window
        if (m_hWnd)
        {
            DestroyWindow(m_hWnd);
            m_hWnd=0;
        }
    }

    HWND GetHwnd()
    {
        return m_hWnd;
    }

protected:
    static LRESULT CALLBACK WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        if (message==WM_USER)
        {
            COptionsHelperWindow *pWnd=(COptionsHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
            if (!pWnd)
                return 0;
            ASSERT(pWnd);
            ASSERT(pWnd->m_pOptions);
            for (int i=0;i<OPTIONS_NUM;i++)
                pWnd->m_pOptions->m_OptionsCache[i].bCached = FALSE;
            EnterCritSection(COptions::m_Sync);
            pWnd->m_pOptions->m_SpeedLimits[0] = COptions::m_sSpeedLimits[0];
            pWnd->m_pOptions->m_SpeedLimits[1] = COptions::m_sSpeedLimits[1];
            LeaveCritSection(COptions::m_Sync);
        }
        return ::DefWindowProc(hWnd, message, wParam, lParam);
    }
    COptions *m_pOptions;

private:
    HWND m_hWnd;
};

/////////////////////////////////////////////////////////////////////////////
// Dialogfeld COptions

COptions::COptions()
{
    for (int i=0;i<OPTIONS_NUM;i++)
        m_OptionsCache[i].bCached=FALSE;
    m_pOptionsHelperWindow=new COptionsHelperWindow(this);
    EnterCritSection(m_Sync);
#ifdef _DEBUG
    for (std::list<COptions *>::iterator iter=m_InstanceList.begin(); iter!=m_InstanceList.end(); iter++)
        ASSERT(*iter!=this);
#endif _DEBUG
    m_InstanceList.push_back(this);
    m_SpeedLimits[0] = m_sSpeedLimits[0];
    m_SpeedLimits[1] = m_sSpeedLimits[1];
    LeaveCritSection(m_Sync);
}

COptions::~COptions()
{
    EnterCritSection(m_Sync);
    std::list<COptions *>::iterator iter;
    for (iter=m_InstanceList.begin(); iter!=m_InstanceList.end(); iter++)
        if (*iter==this)
            break;

    ASSERT(iter!=m_InstanceList.end());
    if (iter != m_InstanceList.end())
        m_InstanceList.erase(iter);
    LeaveCritSection(m_Sync);

    if (m_pOptionsHelperWindow)
        delete m_pOptionsHelperWindow;
    m_pOptionsHelperWindow=0;
}

void COptions::SetOption(int nOptionID, _int64 value, bool save /*=true*/)
{
    switch (nOptionID)
    {
    case OPTION_MAXUSERS:
        if (value<0)
            value=0;
        break;
    case OPTION_THREADNUM:
        if (value<1)
            value=2;
        else if (value>50)
            value=2;
        break;
    case OPTION_TIMEOUT:
        if (value<0)
            value=120;
        else if (value>9999)
            value=120;
        break;
    case OPTION_NOTRANSFERTIMEOUT:
        if (value<600 && value != 0)
            value=600;
        else if (value>9999)
            value=600;
        break;
    case OPTION_LOGINTIMEOUT:
        if (value<0)
            value=60;
        else if (value>9999)
            value=60;
        break;
    case OPTION_ADMINPORT:
        if (value>65535)
            value=14147;
        else if (value<1)
            value=14147;
        break;
    case OPTION_LOGTYPE:
        if (value!=0 && value!=1)
            value = 0;
        break;
    case OPTION_LOGLIMITSIZE:
        if ((value > 999999 || value < 10) && value!=0)
            value = 100;
        break;
    case OPTION_LOGDELETETIME:
        if (value > 999 || value < 0)
            value = 14;
        break;
    case OPTION_DOWNLOADSPEEDLIMITTYPE:
    case OPTION_UPLOADSPEEDLIMITTYPE:
        if (value < 0 || value > 2)
            value = 0;
        break;
    case OPTION_DOWNLOADSPEEDLIMIT:
    case OPTION_UPLOADSPEEDLIMIT:
        if (value > 65535 || value < 1)
            value = 10;
        break;
    case OPTION_BUFFERSIZE:
        if (value < 256 || value > (1024*1024))
            value = 32768;
        break;
    case OPTION_BUFFERSIZE2:
        if (value < 256 || value > (1024*1024*128))
            value = 262144;
        break;
    case OPTION_CUSTOMPASVIPTYPE:
        if (value < 0 || value > 2)
            value = 0;
        break;
    case OPTION_MODEZ_USE:
        if (value < 0 || value > 1)
            value = 0;
        break;
    case OPTION_MODEZ_LEVELMIN:
        if (value < 0 || value > 8)
            value = 1;
        break;
    case OPTION_MODEZ_LEVELMAX:
        if (value < 8 || value > 9)
            value = 9;
        break;
    case OPTION_MODEZ_ALLOWLOCAL:
        if (value < 0 || value > 1)
            value = 0;
        break;
    case OPTION_AUTOBAN_ATTEMPTS:
        if (value < OPTION_AUTOBAN_ATTEMPTS_MIN)
            value = OPTION_AUTOBAN_ATTEMPTS_MIN;
        if (value > OPTION_AUTOBAN_ATTEMPTS_MAX)
            value = OPTION_AUTOBAN_ATTEMPTS_MAX;
        break;
    case OPTION_AUTOBAN_BANTIME:
        if (value < 1)
            value = 1;
        if (value > 999)
            value = 999;
        break;
    }

    Init();

    EnterCritSection(m_Sync);
    m_sOptionsCache[nOptionID-1].nType = 1;
    m_sOptionsCache[nOptionID-1].value = value;
    m_sOptionsCache[nOptionID-1].bCached = TRUE;
    m_OptionsCache[nOptionID-1] = m_sOptionsCache[nOptionID-1];

    LeaveCritSection(m_Sync);

    if (!save)
        return;

    CStdString valuestr;
    valuestr.Format( _T("%I64d"), value);

    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
        return;

    TiXmlDocument document;
    if (!document.LoadFile(bufferA))
        return;

    TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
    if (!pRoot)
        return;

    TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
    if (!pSettings)
        pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

    TiXmlElement* pItem;
    for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
    {
        const char* pName = pItem->Attribute("name");
        if (!pName)
            continue;
        CStdString name(pName);
        if (name != m_Options[nOptionID-1].name)
            continue;

        break;
    }

    if (!pItem)
        pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement();
    pItem->Clear();
    pItem->SetAttribute("name", ConvToNetwork(m_Options[nOptionID-1].name));
    pItem->SetAttribute("type", "numeric");
    pItem->LinkEndChild(new TiXmlText(ConvToNetwork(valuestr)));
    
    document.SaveFile(bufferA);
}

void COptions::SetOption(int nOptionID, LPCTSTR value, bool save /*=true*/)
{
    CStdString str = value;
    Init();

    switch (nOptionID)
    {
    case OPTION_SERVERPORT:
    case OPTION_SSLPORTS:
        {
            std::set<int> portSet;
            
            str.TrimLeft(_T(" ,"));

            int pos = str.FindOneOf(_T(" ,"));
            while (pos != -1)
            {
                int port = _ttoi(str.Left(pos));
                if (port >= 1 && port <= 65535)
                    portSet.insert(port);
                str = str.Mid(pos + 1);
                str.TrimLeft(_T(" ,"));
                pos = str.FindOneOf(_T(" ,"));
            }
            if (str != _T(""))
            {
                int port = _ttoi(str);
                if (port >= 1 && port <= 65535)
                    portSet.insert(port);
            }

            str = _T("");
            for (std::set<int>::const_iterator iter = portSet.begin(); iter != portSet.end(); iter++)
            {
                CStdString tmp;
                tmp.Format(_T("%d "), *iter);
                str += tmp;
            }
            str.TrimRight(' ');
        }
        break;
    case OPTION_WELCOMEMESSAGE:
        {
            std::vector<CStdString> msgLines;
            int oldpos = 0;
            str.Replace(_T("\r\n"), _T("\n"));
            int pos = str.Find(_T("\n"));
            CStdString line;
            while (pos != -1)
            {
                if (pos)
                {
                    line = str.Mid(oldpos, pos - oldpos);
                    line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
                    line.TrimRight(_T(" "));
                    if (msgLines.size() || line != _T(""))
                        msgLines.push_back(line);
                }
                oldpos = pos + 1;
                pos = str.Find(_T("\n"), oldpos);
            }
            line = str.Mid(oldpos);
            if (line != _T(""))
            {
                line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
                msgLines.push_back(line);
            }
            str = _T("");
            for (unsigned int i = 0; i < msgLines.size(); i++)
                str += msgLines[i] + _T("\r\n");
            str.TrimRight(_T("\r\n"));
            if (str == _T(""))
            {
                str = _T("%v");
                str += _T("\r\nwritten by Tim Kosse (Tim.Kosse@gmx.de)");
                str += _T("\r\nPlease visit http://sourceforge.net/projects/filezilla/");
            }
        }
        break;
    case OPTION_ADMINIPBINDINGS:
        {
            CStdString sub;
            std::list<CStdString> ipBindList;
            for (unsigned int i = 0; i<_tcslen(value); i++)
            {
                TCHAR cur = value[i];
                if ((cur < '0' || cur > '9') && cur != '.' && cur != ':')
                {
                    if (sub == _T("") && cur == '*')
                    {
                        ipBindList.clear();
                        ipBindList.push_back(_T("*"));
                        break;
                    }

                    if (sub != _T(""))
                    {
                        if (IsIpAddress(sub))
                            ipBindList.push_back(sub);
                        sub = _T("");
                    }
                }
                else
                    sub += cur;
            }
            if (sub != _T(""))
            {
                if (IsIpAddress(sub))
                    ipBindList.push_back(sub);
            }
            str = _T("");
            for (std::list<CStdString>::iterator iter = ipBindList.begin(); iter!=ipBindList.end(); iter++)
                if (!IsLocalhost(*iter))
                    str += *iter + _T(" ");

            str.TrimRight(_T(" "));
        }
        break;
    case OPTION_ADMINPASS:
        if (str != _T("") && str.GetLength() < 6)
            return;
        break;
    case OPTION_MODEZ_DISALLOWED_IPS:
    case OPTION_IPFILTER_ALLOWED:
    case OPTION_IPFILTER_DISALLOWED:
    case OPTION_ADMINIPADDRESSES:
        {
            str.Replace('\r', ' ');
            str.Replace('\n', ' ');
            str.Replace('\r', ' ');
            while (str.Replace(_T("  "), _T(" ")));
            str += _T(" ");

            CStdString ips;

            int pos = str.Find(' ');
            while (pos != -1)
            {
                CStdString sub = str.Left(pos);
                str = str.Mid(pos + 1);
                str.TrimLeft(' ');

                if (sub == _T("*"))
                    ips += _T(" ") + sub;
                else
                {
                    if (IsValidAddressFilter(sub))
                        ips += " " + sub;
                    pos = str.Find(' ');
                }
            }
            ips.TrimLeft(' ');

            str = ips;
        }
        break;
    case OPTION_IPBINDINGS:
        {
            CStdString sub;
            std::list<CStdString> ipBindList;
            for (unsigned int i = 0; i<_tcslen(value); i++)
            {
                TCHAR cur = value[i];
                if ((cur < '0' || cur > '9') && cur != '.' && cur != ':')
                {
                    if (sub == _T("") && cur == '*')
                    {
                        ipBindList.clear();
                        ipBindList.push_back(_T("*"));
                        break;
                    }

                    if (sub != _T(""))
                    {
                        if (IsIpAddress(sub))
                            ipBindList.push_back(sub);
                        sub = _T("");
                    }
                }
                else
                    sub += cur;
            }
            if (sub != _T(""))
            {
                if (IsIpAddress(sub))
                    ipBindList.push_back(sub);
            }

            if (ipBindList.empty())
                ipBindList.push_back(_T("*"));

            str = _T("");
            for (std::list<CStdString>::iterator iter = ipBindList.begin(); iter != ipBindList.end(); iter++)
                str += *iter + _T(" ");

            str.TrimRight(_T(" "));
        }
        break;
    case OPTION_CUSTOMPASVIPSERVER:
        if (str.Find(_T("filezilla.sourceforge.net")) != -1)
            str = _T("http://ip.filezilla-project.org/ip.php");
        break;
    }
    EnterCritSection(m_Sync);
    m_sOptionsCache[nOptionID-1].bCached = TRUE;
    m_sOptionsCache[nOptionID-1].nType = 0;
    m_sOptionsCache[nOptionID-1].str = str;
    m_OptionsCache[nOptionID-1]=m_sOptionsCache[nOptionID-1];
    LeaveCritSection(m_Sync);

    if (!save)
        return;

    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
        return;

    TiXmlDocument document;
    if (!document.LoadFile(bufferA))
        return;

    TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
    if (!pRoot)
        return;

    TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
    if (!pSettings)
        pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

    TiXmlElement* pItem;
    for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
    {
        const char* pName = pItem->Attribute("name");
        if (!pName)
            continue;
        CStdString name(pName);
        if (name != m_Options[nOptionID-1].name)
            continue;

        break;
    }

    if (!pItem)
        pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement();
    pItem->Clear();
    pItem->SetAttribute("name", ConvToNetwork(m_Options[nOptionID-1].name));
    pItem->SetAttribute("type", "string");
    pItem->LinkEndChild(new TiXmlText(ConvToNetwork(value)));
    
    document.SaveFile(bufferA);
}

CStdString COptions::GetOption(int nOptionID)
{
    ASSERT(nOptionID>0 && nOptionID<=OPTIONS_NUM);
    ASSERT(!m_Options[nOptionID-1].nType);
    Init();

    if (m_OptionsCache[nOptionID-1].bCached)
        return m_OptionsCache[nOptionID-1].str;

    EnterCritSection(m_Sync);

    if (!m_sOptionsCache[nOptionID-1].bCached)
    {
        //Default values
        switch (nOptionID)
        {
        case OPTION_SERVERPORT:
            m_sOptionsCache[nOptionID-1].str = _T("21");
            break;
        case OPTION_WELCOMEMESSAGE:
            m_sOptionsCache[nOptionID-1].str = _T("%v");
            m_sOptionsCache[nOptionID-1].str += _T("\r\nwritten by Tim Kosse (Tim.Kosse@gmx.de)");
            m_sOptionsCache[nOptionID-1].str += _T("\r\nPlease visit http://sourceforge.net/projects/filezilla/");
            break;
        case OPTION_CUSTOMPASVIPSERVER:
            m_sOptionsCache[nOptionID-1].str = _T("http://ip.filezilla-project.org/ip.php");
            break;
        case OPTION_IPBINDINGS:
            m_sOptionsCache[nOptionID-1].str = _T("*");
            break;
        case OPTION_SSLPORTS:
            m_sOptionsCache[nOptionID-1].str = _T("990");
            break;
        default:
            m_sOptionsCache[nOptionID-1].str = _T("");
            break;
        }
        m_sOptionsCache[nOptionID-1].bCached = TRUE;
        m_sOptionsCache[nOptionID-1].nType = 0;
    }
    m_OptionsCache[nOptionID-1] = m_sOptionsCache[nOptionID - 1];
    LeaveCritSection(m_Sync);
    return m_OptionsCache[nOptionID-1].str;
}

_int64 COptions::GetOptionVal(int nOptionID)
{
    ASSERT(nOptionID>0 && nOptionID<=OPTIONS_NUM);
    ASSERT(m_Options[nOptionID-1].nType == 1);
    Init();

    if (m_OptionsCache[nOptionID-1].bCached)
        return m_OptionsCache[nOptionID-1].value;

    EnterCritSection(m_Sync);

    if (!m_sOptionsCache[nOptionID-1].bCached)
    {
        //Default values
        switch (nOptionID)
        {
            case OPTION_MAXUSERS:
                m_sOptionsCache[nOptionID-1].value = 0;
                break;
            case OPTION_THREADNUM:
                m_sOptionsCache[nOptionID-1].value = 2;
                break;
            case OPTION_TIMEOUT:
            case OPTION_NOTRANSFERTIMEOUT:
                m_sOptionsCache[nOptionID-1].value = 120;
                break;
            case OPTION_LOGINTIMEOUT:
                m_sOptionsCache[nOptionID-1].value = 60;
                break;
            case OPTION_ADMINPORT:
                m_sOptionsCache[nOptionID-1].value = 14147;
                break;
            case OPTION_DOWNLOADSPEEDLIMIT:
            case OPTION_UPLOADSPEEDLIMIT:
                m_sOptionsCache[nOptionID-1].value = 10;
                break;
            case OPTION_BUFFERSIZE:
                m_sOptionsCache[nOptionID-1].value = 32768;
                break;
            case OPTION_CUSTOMPASVIPTYPE:
                m_sOptionsCache[nOptionID-1].value = 0;
                break;
            case OPTION_MODEZ_USE:
                m_sOptionsCache[nOptionID-1].value = 0;
                break;
            case OPTION_MODEZ_LEVELMIN:
                m_sOptionsCache[nOptionID-1].value = 1;
                break;
            case OPTION_MODEZ_LEVELMAX:
                m_sOptionsCache[nOptionID-1].value = 9;
                break;
            case OPTION_MODEZ_ALLOWLOCAL:
                m_sOptionsCache[nOptionID-1].value = 0;
                break;
            case OPTION_ALLOWEXPLICITSSL:
                m_sOptionsCache[nOptionID-1].value = 1;
                break;
            case OPTION_BUFFERSIZE2:
                m_sOptionsCache[nOptionID-1].value = 65536;
                break;
            case OPTION_NOEXTERNALIPONLOCAL:
                m_sOptionsCache[nOptionID-1].value = 1;
                break;
            case OPTION_ACTIVE_IGNORELOCAL:
                m_sOptionsCache[nOptionID-1].value = 1;
                break;
            case OPTION_AUTOBAN_BANTIME:
                m_sOptionsCache[nOptionID-1].value = 1;
                break;
            case OPTION_AUTOBAN_ATTEMPTS:
                m_sOptionsCache[nOptionID-1].value = 10;
                break;
            default:
                m_sOptionsCache[nOptionID-1].value = 0;
        }
        m_sOptionsCache[nOptionID-1].bCached=TRUE;
        m_sOptionsCache[nOptionID-1].nType=1;
    }
    m_OptionsCache[nOptionID-1]=m_sOptionsCache[nOptionID-1];
    LeaveCritSection(m_Sync);
    return m_OptionsCache[nOptionID-1].value;
}

void COptions::UpdateInstances()
{
    EnterCritSection(m_Sync);
    for (std::list<COptions *>::iterator iter=m_InstanceList.begin(); iter!=m_InstanceList.end(); iter++)
    {
        ASSERT((*iter)->m_pOptionsHelperWindow);
        ::PostMessage((*iter)->m_pOptionsHelperWindow->GetHwnd(), WM_USER, 0, 0);
    }
    LeaveCritSection(m_Sync);
}

void COptions::Init()
{
    if (m_bInitialized)
        return;
    EnterCritSection(m_Sync);
    m_bInitialized = TRUE;
    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    for (int i = 0; i < OPTIONS_NUM; i++)
        m_sOptionsCache[i].bCached = FALSE;

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlDocument document;

    CFileStatus64 status;
    if (!GetStatus64(buffer, status) )
    {
        document.LinkEndChild(new TiXmlElement("FileZillaServer"));
        document.SaveFile(bufferA);
    }
    else if (status.m_attribute & FILE_ATTRIBUTE_DIRECTORY)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    if (!document.LoadFile(bufferA))
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
    if (!pRoot)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
    if (!pSettings)
        pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

    TiXmlElement* pItem;
    for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
    {
        const char* pName = pItem->Attribute("name");
        if (!pName)
            continue;
        CStdString name(pName);

        const char* pType = pItem->Attribute("type");
        if (!pType)
            continue;
        CStdString type(pType);

        TiXmlNode* textNode = pItem->FirstChild();
        CStdString value;
        if (textNode && textNode->ToText())
            value = ConvFromNetwork(textNode->Value());
        else if (type == _T("numeric"))
            continue;

        for (int i = 0; i < OPTIONS_NUM; i++)
        {
            if (!_tcscmp(name, m_Options[i].name))
            {
                if (m_sOptionsCache[i].bCached)
                    break;

                if (type == _T("numeric"))
                {
                    if (m_Options[i].nType != 1)
                        break;
                    _int64 value64 = _ttoi64(value);
                    if (IsNumeric(value))
                        SetOption(i + 1, value64, false);
                }
                else
                {
                    if (m_Options[i].nType != 0)
                        break;
                    SetOption(i + 1, value, false);
                }
                break;
            }
        }
    }
    ReadSpeedLimits(pSettings);

    LeaveCritSection(m_Sync);
    UpdateInstances();
    return;
}

bool COptions::IsNumeric(LPCTSTR str)
{
    if (!str)
        return false;
    LPCTSTR p=str;
    while(*p)
    {
        if (*p<'0' || *p>'9')
        {
            return false;
        }
        p++;
    }
    return true;
}

TiXmlElement *COptions::GetXML()
{
    EnterCritSection(m_Sync);
    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
    {
        LeaveCritSection(m_Sync);
        return 0;
    }

    TiXmlDocument *pDocument = new TiXmlDocument;
    
    if (!pDocument->LoadFile(bufferA))
    {
        LeaveCritSection(m_Sync);
        delete pDocument;
        return NULL;
    }

    TiXmlElement* pElement = pDocument->FirstChildElement("FileZillaServer");
    if (!pElement)
    {
        LeaveCritSection(m_Sync);
        delete pDocument;
        return NULL;
    }

    return pElement;
}

BOOL COptions::FreeXML(TiXmlElement *pXML, bool save)
{
    ASSERT(pXML);
    if (!pXML)
        return FALSE;

    if (!save)
    {
        delete pXML->GetDocument();
        LeaveCritSection(m_Sync);
        return FALSE;
    }

    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
    {
        delete pXML->GetDocument();
        LeaveCritSection(m_Sync);
        return FALSE;
    }

    if (!pXML->GetDocument()->SaveFile(bufferA))
    {
        delete pXML->GetDocument();
        LeaveCritSection(m_Sync);
        return FALSE;
    }

    delete pXML->GetDocument();
    LeaveCritSection(m_Sync);
    return TRUE;
}

BOOL COptions::GetAsCommand(char **pBuffer, DWORD *nBufferLength)
{
    int i;
    DWORD len = 2;

    EnterCritSection(m_Sync);
    for (i=0; i<OPTIONS_NUM; i++)
    {
        len+=1;
        if (!m_Options[i].nType)
        {
            len += 3;
            char* utf8 = ConvToNetwork(GetOption(i + 1));
            if (utf8)
            {
                if ((i+1) != OPTION_ADMINPASS)
                    len += strlen(utf8);
                else
                {
                    if (GetOption(i+1).GetLength() < 6 && *utf8)
                        len++;
                }
                delete [] utf8;
            }
        }
        else
            len+=8;
    }

    len += 4;
    SPEEDLIMITSLIST::const_iterator iter;
    for (i = 0; i < 2; i++)
        for (iter = m_sSpeedLimits[i].begin(); iter != m_sSpeedLimits[i].end(); iter++)
            len += iter->GetRequiredBufferLen();

    *pBuffer=new char[len];
    char *p=*pBuffer;
    *p++ = OPTIONS_NUM/256;
    *p++ = OPTIONS_NUM%256;
    for (i=0; i<OPTIONS_NUM; i++)
    {
        *p++ = m_Options[i].nType;
        switch(m_Options[i].nType) {
        case 0:
            {
                CStdString str = GetOption(i+1);
                if ((i+1)==OPTION_ADMINPASS) //Do NOT send admin password,
                                             //instead send empty string if admin pass is set
                                             //and send a single char if admin pass is invalid (len < 6)
                {
                    if (str.GetLength() >= 6 || str == _T(""))
                        str = _T("");
                    else
                        str = _T("*");
                }

                char* utf8 = ConvToNetwork(str);
                if (!utf8)
                {
                    *p++ = 0;
                    *p++ = 0;
                    *p++ = 0;
                }
                else
                {
                    int len = strlen(utf8);
                    *p++ = (len / 256) / 256;
                    *p++ = len / 256;
                    *p++ = len % 256;
                    memcpy(p, utf8, len);
                    p += len;
                    delete [] utf8;
                }
            }
            break;
        case 1:
            {
                _int64 value = GetOptionVal(i+1);
                memcpy(p, &value, 8);
                p+=8;
            }
            break;
        default:
            ASSERT(FALSE);
        }
    }

    for (i = 0; i < 2; i++)
    {
        *p++ = m_sSpeedLimits[i].size() << 8;
        *p++ = m_sSpeedLimits[i].size() %256;
        for (iter = m_sSpeedLimits[i].begin(); iter != m_sSpeedLimits[i].end(); iter++)
            p = iter->FillBuffer(p);
    }

    LeaveCritSection(m_Sync);

    *nBufferLength = len;

    return TRUE;
}

BOOL COptions::ParseOptionsCommand(unsigned char *pData, DWORD dwDataLength, BOOL bFromLocal /*=FALSE*/)
{
    unsigned char *p = pData;
    int num = *p * 256 + p[1];
    p+=2;
    if (num!=OPTIONS_NUM)
        return FALSE;

    int i;
    for (i = 0; i < num; i++)
    {
        if ((DWORD)(p-pData)>=dwDataLength)
            return FALSE;
        int nType = *p++;
        if (!nType)
        {
            if ((DWORD)(p-pData+3) >= dwDataLength)
                return 2;
            int len = *p * 256 * 256 + p[1] * 256 + p[2];
            p += 3;
            if ((DWORD)(p - pData + len) > dwDataLength)
                return FALSE;
            char *pBuffer = new char[len + 1];
            memcpy(pBuffer, p, len);
            pBuffer[len]=0;
            if (!m_Options[i].bOnlyLocal || bFromLocal) //Do not change admin interface settings from remote connections
#ifdef _UNICODE
                SetOption(i+1, ConvFromNetwork(pBuffer), false);
#else
                SetOption(i+1, ConvToLocal(ConvFromNetwork(pBuffer)), false);
#endif
            delete [] pBuffer;
            p+=len;
        }
        else if (nType == 1)
        {
            if ((DWORD)(p-pData+8)>dwDataLength)
                return FALSE;
            if (!m_Options[i].bOnlyLocal || bFromLocal) //Do not change admin interface settings from remote connections
                SetOption(i+1, GET64(p), false);
            p+=8;
        }
        else
            return FALSE;
    }

    SPEEDLIMITSLIST dl;
    SPEEDLIMITSLIST ul;

    if ((DWORD)(p-pData+2)>dwDataLength)
        return FALSE;
    num = *p++ << 8;
    num |= *p++;
    EnterCritSection(m_Sync);
    for (i=0; i<num; i++)
    {
        CSpeedLimit limit;
        p = limit.ParseBuffer(p, dwDataLength - (p - pData));
        if (!p)
        {
            LeaveCritSection(m_Sync);
            return FALSE;
        }
        dl.push_back(limit);
    }

    if ((DWORD)(p-pData+2)>dwDataLength)
    {
        LeaveCritSection(m_Sync);
        return FALSE;
    }
    num = *p++ << 8;
    num |= *p++;
    for (i=0; i<num; i++)
    {
        CSpeedLimit limit;
        p = limit.ParseBuffer(p, dwDataLength - (p - pData));
        if (!p)
        {
            LeaveCritSection(m_Sync);
            return FALSE;
        }
        ul.push_back(limit);
    }

    m_sSpeedLimits[0] = dl;
    m_sSpeedLimits[1] = ul;

    SaveOptions();

    LeaveCritSection(m_Sync);

    UpdateInstances();

    return TRUE;
}

static void SetText(TiXmlElement* pElement, const CStdString& text)
{
    pElement->Clear();
    pElement->LinkEndChild(new TiXmlText(ConvToNetwork(text)));
}

BOOL COptions::SaveSpeedLimits(TiXmlElement* pSettings)
{
    TiXmlElement* pSpeedLimits;
    while ((pSpeedLimits = pSettings->FirstChildElement("SpeedLimits")))
        pSettings->RemoveChild(pSpeedLimits);
    
    pSpeedLimits = pSettings->LinkEndChild(new TiXmlElement("SpeedLimits"))->ToElement();

    const char* names[] = { "Download", "Upload" };

    for (int i = 0; i < 2; i++)
    {
        TiXmlElement* pSpeedLimit = new TiXmlElement(names[i]);
        pSpeedLimits->LinkEndChild(pSpeedLimit);

        for (unsigned int j = 0; j < m_sSpeedLimits[i].size(); j++)
        {
            CSpeedLimit limit = m_sSpeedLimits[i][j];

            TiXmlElement* pRule = pSpeedLimit->LinkEndChild(new TiXmlElement("Rule"))->ToElement();
            limit.Save(pRule);
        }
    }

    return TRUE;
}

CStdString ReadText(TiXmlElement* pElement)
{
    TiXmlNode* textNode = pElement->FirstChild();
    if (!textNode || !textNode->ToText())
        return _T("");

    return ConvFromNetwork(textNode->Value());                    
}

BOOL COptions::ReadSpeedLimits(TiXmlElement *pXML)
{
    const char* names[] = { "Download", "Upload" };

    for (int i = 0; i < 2; i++)
    {
        for (TiXmlElement* pSpeedLimits = pXML->FirstChildElement("SpeedLimits"); pSpeedLimits; pSpeedLimits = pSpeedLimits->NextSiblingElement("SpeedLimits"))
        {
            for (TiXmlElement* pLimit = pSpeedLimits->FirstChildElement(names[i]); pLimit; pLimit = pLimit->NextSiblingElement(names[i]))
            {
                for (TiXmlElement* pRule = pLimit->FirstChildElement("Rule"); pRule; pRule = pRule->NextSiblingElement("Rule"))
                {
                    CSpeedLimit limit;
                    if (!limit.Load(pRule))
                        continue;

                    if (m_sSpeedLimits[i].size() < 20000)
                        m_sSpeedLimits[i].push_back(limit);
                }
            }
        }
    }
    
    return TRUE;
}

int COptions::GetCurrentSpeedLimit(int nMode)
{
    Init();

    int type[2] = { OPTION_DOWNLOADSPEEDLIMITTYPE, OPTION_UPLOADSPEEDLIMITTYPE };
    int limit[2] = { OPTION_DOWNLOADSPEEDLIMIT, OPTION_UPLOADSPEEDLIMIT };

    int nType = (int)GetOptionVal(type[nMode]);
    switch (nType)
    {
    case 0:
        return -1;
    case 1:
        return (int)GetOptionVal(limit[nMode]);
    default:
        {
            SYSTEMTIME s;
            GetLocalTime(&s);
            for (SPEEDLIMITSLIST::const_iterator iter = m_SpeedLimits[nMode].begin(); iter != m_SpeedLimits[nMode].end(); iter++)
                if (iter->IsItActive(s))
                    return iter->m_Speed;
            return -1;
        }
    }
}

void COptions::ReloadConfig()
{
    EnterCritSection(m_Sync);

    m_bInitialized = TRUE;
    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos = _tcsrchr(buffer, '\\');
    if (pos)
        *++pos = 0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    for (int i = 0; i < OPTIONS_NUM; i++)
        m_sOptionsCache[i].bCached = FALSE;

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlDocument document;

    CFileStatus64 status;
    if (!GetStatus64(buffer, status) )
    {
        document.LinkEndChild(new TiXmlElement("FileZillaServer"));
        document.SaveFile(bufferA);
    }
    else if (status.m_attribute & FILE_ATTRIBUTE_DIRECTORY)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    if (!document.LoadFile(bufferA))
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
    if (!pRoot)
    {
        LeaveCritSection(m_Sync);
        return;
    }

    TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
    if (!pSettings)
        pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

    TiXmlElement* pItem;
    for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
    {
        const char* pName = pItem->Attribute("name");
        if (!pName)
            continue;
        CStdString name(pName);
        const char* pType = pItem->Attribute("type");
        if (!pType)
            continue;
        CStdString type(pType);
        TiXmlNode* textNode = pItem->FirstChild();
        if (!textNode || !textNode->ToText())
            continue;
        CStdString value = ConvFromNetwork(textNode->Value());


        for (int i = 0;i < OPTIONS_NUM; i++)
        {
            if (!_tcscmp(name, m_Options[i].name))
            {
                if (m_sOptionsCache[i].bCached)
                    break;

                if (type == _T("numeric"))
                {
                    if (m_Options[i].nType != 1)
                        break;
                    _int64 value64 = _ttoi64(value);
                    if (IsNumeric(value))
                        SetOption(i + 1, value64, false);
                }
                else
                {
                    if (m_Options[i].nType != 0)
                        break;
                    SetOption(i  +1, value, false);
                }
                break;
            }
        }
    }
    ReadSpeedLimits(pSettings);

    LeaveCritSection(m_Sync);
    UpdateInstances();
}

void COptions::SaveOptions()
{
    TCHAR buffer[MAX_PATH + 1000]; //Make it large enough
    GetModuleFileName( 0, buffer, MAX_PATH );
    LPTSTR pos=_tcsrchr(buffer, '\\');
    if (pos)
        *++pos=0;
    _tcscat(buffer, _T("FileZilla Server.xml"));

    USES_CONVERSION;
    char* bufferA = T2A(buffer);
    if (!bufferA)
        return;

    TiXmlDocument document;
    if (!document.LoadFile(bufferA))
        return;

    TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
    if (!pRoot)
        return;

    TiXmlElement* pSettings;
    while ((pSettings = pRoot->FirstChildElement("Settings")))
        pRoot->RemoveChild(pSettings);
    pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

    for (unsigned int i = 0; i < OPTIONS_NUM; i++)
    {
        if (!m_OptionsCache[i].bCached)
            continue;

        CStdString valuestr;
        if (!m_OptionsCache[i].nType)
            valuestr = m_OptionsCache[i].str;
        else
            valuestr.Format( _T("%I64d"), m_OptionsCache[i].value);

        TiXmlElement* pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement();
        pItem->SetAttribute("name", ConvToNetwork(m_Options[i].name));
        if (!m_OptionsCache[i].nType)
            pItem->SetAttribute("type", "string");
        else
            pItem->SetAttribute("type", "numeric");
        pItem->LinkEndChild(new TiXmlText(ConvToNetwork(valuestr)));
    }

    SaveSpeedLimits(pSettings);

    document.SaveFile(bufferA);
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0312 ]--