⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 epocstore.cpp

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*    epocstore.cpp * * Symbian OS implementation of PuTTY settings storage interface * * Mostly copied from the SyOSsh EPOC Release 5 port by Gabor Keresztfalvi, * some additional fixes for the current Symbian port by Petteri Kangaslampi. * Originally based on winstore.c in the PuTTY distribution. * * [No copyright messages in the original, assumed to be copyrighted by *  Gabor Keresztfavli and available through the PuTTY license] * * Portions copyright 2002,2003 Petteri Kangaslampi * * See license.txt for full copyright and license information.*//* * epocstore.cpp: EPOC-specific implementation of the interface * defined in storage.h. * FIXME: Partially this is a stub only... */#include <e32base.h>#include <f32file.h>#include <bautils.h>#include <stdio.h>#include <stdlib.h>extern "C" {#include "putty.h"#include "storage.h"#include "tree234.h"}#include "epocstore.h"#include <assert.h>#include "charutil.h"// Current settingsstruct TSetting {    HBufC8 *iName;    HBufC8 *iValue;};// Static bits (ugly, but the API gives us no choice - otherwise the data path// would have to be hardcoded)struct TStoreStatics {    TFileName iDataPath;    RFs iFs;};#define storeStatics ((TStoreStatics *const)((SymbianStatics *const)statics()->platform)->store_state)// Settings read statestruct TSettingsReadState {    tree234 *iSettings;};// Settings write statestruct TSettingsWriteState {    RFile iFile;};_LIT(KRandomFile,"random.dat");_LIT(KHostKeysFile,"hostkeys.dat");_LIT(KTmpHostKeysFile, "hostkeys.tmp");_LIT8(KSettingsId, "[PuTTYConfig]");_LIT8(KCRLF, "\r\n");static void FreeSettingsTree(tree234 *aSettings);void epoc_store_init(const TDesC &aDataPath) {        // Allocate memory for statics    TStoreStatics *statics = new TStoreStatics;    if ( !statics )        fatalbox("Out of memory");    ((SymbianStatics*)statics()->platform)->store_state = statics;    assert(aDataPath.Length() > 1);    storeStatics->iDataPath = aDataPath;        // Make sure the path ends with a backslash    if ( storeStatics->iDataPath[storeStatics->iDataPath.Length()-1] != '\\' ) {        storeStatics->iDataPath.Append('\\');    }    TInt err = storeStatics->iFs.Connect();    if ( err != KErrNone )        fatalbox("File server connect failed");}void epoc_store_free() {    TStoreStatics *statics =        ((TStoreStatics*)((SymbianStatics*)statics()->platform)->store_state);    statics->iFs.Close();    delete statics;    ((SymbianStatics*)statics()->platform)->store_state = NULL;}/** * An utility class for reading files one line at a time. Handles all * related buffering and line feed conversion issues. */class CLineReader : public CBase {public:    /**      * Creates a new CLineReader object and pushes it to the cleanup stack.     *      * @param aFileName The file to read     * @param aFs       The file server session to use     *      * @return A new CLineReader object     */    static CLineReader *NewLC(const TDesC &aFileName, RFs &aFs);    /**      * Destructor.     */    ~CLineReader();    /**      * Reads a line from the input file. Empty lines are discarded,     * and the cr/lf characters are removed. Returns an empty     * descriptor if called at the end of the file.     *      * @return The line that was read, or an empty descriptor if at EOF.     */    TPtrC8 &ReadLineL();private:    CLineReader();    void ConstructL(const TDesC &aFileName, RFs &aFs);    TBool ReadDataL();    TUint8 *iBuffer;    TUint iBufSize;    TUint iDataLength;    TUint iLineEnd;    TUint iLineStart;    TPtrC8 iThisLine;    RFs *iFs;    RFile iFile;    TBool iFileOpen;};// Builds a new line reader objectCLineReader *CLineReader::NewLC(const TDesC &aFileName, RFs &aFs) {    CLineReader *self = new (ELeave) CLineReader;    CleanupStack::PushL(self);    self->ConstructL(aFileName, aFs);    return self;}CLineReader::CLineReader() : iThisLine(NULL, 0) {    iFileOpen = EFalse;    }void CLineReader::ConstructL(const TDesC &aFileName, RFs &aFs) {    iFs = &aFs;    User::LeaveIfError(iFile.Open(*iFs, aFileName, EFileShareReadersOnly));    iFileOpen = ETrue;    iBufSize = 512;    iDataLength = 0;    iLineEnd = 0;    iBuffer = new (ELeave) TUint8[iBufSize];}CLineReader::~CLineReader() {    if ( iFileOpen ) {        iFile.Close();    }    delete iBuffer;}// Reads a line from the file. Empty lines are discarded, and the cr/lf// characters are removed. Returns an empty descriptor if at the end of the// file.TPtrC8 &CLineReader::ReadLineL() {    // Discard previous line    if ( iLineEnd > 0 ) {        assert(iLineEnd <= iDataLength);        if ( iLineEnd < iDataLength ) {            Mem::Copy(&iBuffer[0], &iBuffer[iLineEnd], iDataLength - iLineEnd);            iDataLength -= iLineEnd;        }        iLineEnd = 0;    }    iLineStart = 0;    // Find where the next line starts, skipping any linefeed characters    TBool startFound = EFalse;    while ( !startFound ) {        // Read more data if necessary        if ( iLineStart >= iDataLength ) {            if ( !ReadDataL() ) {                // EOF                iThisLine.Set(NULL, 0);                return iThisLine;            }        }        // Does the line start here?        if ( (iBuffer[iLineStart] != '\r') && (iBuffer[iLineStart] != '\n') ) {            startFound = ETrue;        } else {            iLineStart++;        }    }    // Find where the line ends    iLineEnd = iLineStart;    TBool endFound = EFalse;    while ( !endFound ) {        // Read more data if necessary        if ( iLineEnd >= iDataLength ) {            if ( !ReadDataL() ) {                // EOF -- use last line if we have one                if ( iLineEnd > iLineStart ) {                    iThisLine.Set(&iBuffer[iLineStart], iLineEnd - iLineStart);                } else {                    iThisLine.Set(NULL, 0);                }                return iThisLine;            }        }        // Does the line end here?        if ( (iBuffer[iLineEnd] == '\r') || (iBuffer[iLineEnd] == '\n') ) {            endFound = ETrue;        } else {            iLineEnd++;        }            }    // OK, we have the line    iThisLine.Set(&iBuffer[iLineStart], iLineEnd - iLineStart);    return iThisLine;}// Internal: Reads more data to the internal buffer. Returns EFalse if at the// EOF and couldn't read more.TBool CLineReader::ReadDataL() {    // Need a bigger buffer?    if ( iDataLength >= iBufSize ) {        TUint newSize = 2 * iBufSize;        TUint8 *newBuf = new (ELeave) TUint8[newSize];        Mem::Copy(newBuf, iBuffer, iBufSize);        delete [] iBuffer;        iBuffer = newBuf;        iBufSize = newSize;    }    // Read some data    assert(iBufSize > iDataLength);    assert(iFileOpen);    TPtr8 ptr(&iBuffer[iDataLength], iBufSize - iDataLength);    User::LeaveIfError(iFile.Read(ptr));    if ( ptr.Length() == 0 ) {        return EFalse;    }    iDataLength += ptr.Length();    return ETrue;}// Comparison function for sorting settings in the settings tree. Compared// two TSetting objectsstatic int cmp_setting_setting(void *s1, void *s2) {    TSetting *set1 = (TSetting*) s1;    TSetting *set2 = (TSetting*) s2;    return set1->iName->Compare(*set2->iName);}// Comparison function for looking up settings from the settings tree. Compares// a char* string to a TSetting objectstatic int cmp_name_setting(void *n, void *s) {    char *str = (char*) n;    TSetting *set = (TSetting*) s;    TPtrC8 ptr((TUint8*) str);    return ptr.Compare(*set->iName);}static void open_settings_w_L(TSettingsWriteState* state,                              const char *sessionname) {    // FIXME: Writing settings is pretty slow, and could be optimized by    // gathering all settings to a buffer and writing that buffer in one go.        // sessionname is really an absolute path to the settings file    HBufC *buf = HBufC::NewLC(strlen(sessionname));    TPtr ptr = buf->Des();    StringToDes(sessionname, ptr);    // Open the file and write header    User::LeaveIfError(state->iFile.Replace(storeStatics->iFs, ptr,                                            EFileWrite));    CleanupClosePushL(state->iFile);    User::LeaveIfError(state->iFile.Write(KSettingsId));    User::LeaveIfError(state->iFile.Write(KCRLF));    CleanupStack::Pop(); // file    CleanupStack::PopAndDestroy(buf);}void *open_settings_w(const char *sessionname, char **errmsg) {        TSettingsWriteState *state = snew(TSettingsWriteState);    if ( !state ) {        *errmsg = "Out of memory";        return NULL;    }        TRAPD(error, open_settings_w_L(state, sessionname));    if ( error != KErrNone ) {        sfree(state);        *errmsg = "Failed top open settings file";    }    return (void*) state;}static void write_settings_s_L(TSettingsWriteState *state, const char *key,                               const char *value) {    // key = value\r\n\0    HBufC8 *buf = HBufC8::NewLC(strlen(key) + strlen(value) + 6);    TPtr8 ptr = buf->Des();    char *strbuf = (char*) ptr.Ptr();    sprintf(strbuf, "%s = %s\r\n", key, value);    ptr.SetLength(strlen(strbuf));    User::LeaveIfError(state->iFile.Write(ptr));    CleanupStack::PopAndDestroy();}void write_setting_s(void *handle, const char *key, const char *value) {    TSettingsWriteState *state = (TSettingsWriteState*) handle;    TRAPD(error, write_settings_s_L(state, key, value));    if ( error != KErrNone ) {        fatalbox("write_setting_s: error %d", error);    }}static void write_settings_i_L(TSettingsWriteState *state, const char *key,                               int value) {    // key = 4294967296\r\n\0    HBufC8 *buf = HBufC8::NewLC(strlen(key) + 10 + 6);    TPtr8 ptr = buf->Des();    char *strbuf = (char*) ptr.Ptr();    sprintf(strbuf, "%s = %u\r\n", key, value);    ptr.SetLength(strlen(strbuf));    User::LeaveIfError(state->iFile.Write(ptr));    CleanupStack::PopAndDestroy();}void write_setting_i(void *handle, const char *key, int value) {        TSettingsWriteState *state = (TSettingsWriteState*) handle;    TRAPD(error, write_settings_i_L(state, key, value));    if ( error != KErrNone ) {        fatalbox("write_setting_s: error %d", error);    }}void close_settings_w(void *handle) {    TSettingsWriteState *state = (TSettingsWriteState*) handle;    state->iFile.Close();    sfree(state);}static void open_settings_r_L(TSettingsReadState *state,                               const char *sessionname) {        // sessionname is really an absolute path to the settings file. We'll just    // read the whole file into a tree and use it when the actual setting    // values are requested.    HBufC *buf = HBufC::NewLC(strlen(sessionname));    TPtr namePtr = buf->Des();    StringToDes(sessionname, namePtr);        // Create a new settings tree    tree234 *settings = newtree234(cmp_setting_setting);    if ( settings == NULL ) {        User::Leave(KErrNoMemory);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -