Пример #1
0
void PlatformContextGl::setupDeviceContext() {
	int iFormat;
	PIXELFORMATDESCRIPTOR pfd;
	BOOL err;

	ZeroMemory(&pfd, sizeof(pfd));
	pfd.nSize= sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion= 1;
	pfd.dwFlags= PFD_GENERIC_ACCELERATED | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType= PFD_TYPE_RGBA;
	pfd.cColorBits= m_colorBits;
	pfd.cDepthBits= m_depthBits;
	pfd.iLayerType= PFD_MAIN_PLANE;
	pfd.cStencilBits= m_stencilBits;

	iFormat = ChoosePixelFormat(dch, &pfd);
	if (!iFormat) {
		std::stringstream msg;
		msg << "ChoosePixelFormat() failed.\n" << getLastErrorMsg();
		throw runtime_error(msg.str());
	}
	err = SetPixelFormat(dch, iFormat, &pfd);
	if (!err) {
		std::stringstream msg;
		msg << "SetPixelFormat() failed.\n" << getLastErrorMsg();
		throw runtime_error(msg.str());
	}
}
long openPortByName(char** ppszError, char* pszDeviceName, long baudRate,
                    long  options) {
    int hPort = 0;
    int openFlags = 0;
    ppszError = malloc(sizeof(char *));

    /* do not become the controlling tty */
    openFlags = O_RDWR | O_NOCTTY;
    hPort = open(pszDeviceName, openFlags);
    if (hPort < 0) {
      *ppszError = getLastErrorMsg("open failed");
      return -1;
    }
    /* Set exclusive use flag to block other open calls with EBUSY. */
    //ioctl(hPort, TIOCEXCL, 0);

    configurePort(ppszError, hPort, baudRate, options);

    if (*ppszError != NULL) {
        close(hPort);
        return -1;
    }

    return (int)hPort;
}
Пример #3
0
int WASocketConnection::read(unsigned char *buf, int length)
{
    int result = Netlib_Recv(this->hConn, (char*)buf, length, MSG_NODUMP);
    if (result <= 0)
        throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_RECV);

    return result;
}
Пример #4
0
unsigned char WASocketConnection::read()
{
    SetLastError(0);

    char c;
    int result = Netlib_Recv(this->hConn, &c, 1, 0);
    if (result <= 0)
        throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_RECV);

    return c;
}
Пример #5
0
void WASocketConnection::write(const std::vector<unsigned char> &bytes, int length)
{
    NETLIBBUFFER nlb;
    std::string tmpBuf = std::string(bytes.begin(), bytes.end());
    nlb.buf = (char*)&(tmpBuf.c_str()[0]);
    nlb.len = length;
    nlb.flags = MSG_NODUMP;

    int result = CallService(MS_NETLIB_SEND, WPARAM(hConn), LPARAM(&nlb));
    if (result < length) {
        throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_SEND);
    }
}
Пример #6
0
WASocketConnection::WASocketConnection(const std::string &dir, int port) throw (WAException)
{
    NETLIBOPENCONNECTION	noc = { sizeof(noc) };
    noc.szHost = dir.c_str();
    noc.wPort = port;
    noc.flags = NLOCF_V2; // | NLOCF_SSL;
    this->hConn = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, reinterpret_cast<WPARAM>(this->hNetlibUser),
                                      reinterpret_cast<LPARAM>(&noc));
    if (this->hConn == NULL)
        throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_OPEN);

    this->connected = true;
}
Пример #7
0
unsigned char WASocketConnection::read() {
	char c;

	SetLastError(0);
	int result;
	//do {
		result = Netlib_Recv(this->hConn, &c, 1, 0 /*MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP*/);
	//} while  (WSAGetLastError() == EINTR);
	if (result <= 0) {
		throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_RECV);
	}
	return c;
}
Пример #8
0
void WASocketConnection::write(int i) {
	char buffer;
	buffer = (char) i;

	NETLIBBUFFER nlb;
	nlb.buf = &buffer;
	nlb.len = 1;
	nlb.flags = MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP;

	int result = CallService(MS_NETLIB_SEND, reinterpret_cast<WPARAM>(this->hConn), reinterpret_cast<LPARAM>(&nlb));
	if (result < 1) {
		throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_SEND);
	}
}
Пример #9
0
void WASocketConnection::write(const std::vector<unsigned char>& bytes, int offset, int length)
{
	NETLIBBUFFER nlb;
	std::string tmpBuf = std::string(bytes.begin(), bytes.end()); 
	nlb.buf = (char*) &(tmpBuf.c_str()[offset]);
	nlb.len = length;
	nlb.flags = 0; //MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP;

	int result = CallService(MS_NETLIB_SEND, reinterpret_cast<WPARAM>(this->hConn),
		reinterpret_cast<LPARAM>(&nlb));
	if (result < length) {
		throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_SEND);
	}
}
Пример #10
0
int WASocketConnection::read(std::vector<unsigned char>& b, int off, int length)
{
    if (off < 0 || length < 0)
        throw new WAException("Out of bounds", WAException::SOCKET_EX, WAException::SOCKET_EX_RECV);

    char* buffer = (char*)_alloca(length);
    int result = Netlib_Recv(this->hConn, buffer, length, MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP);
    if (result <= 0)
        throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_RECV);

    for (int i = 0; i < result; i++)
        b[off + i] = buffer[i];

    return result;
}
long readFromPort(char** ppszError, long hPort, char* pBuffer,
                 long nNumberOfBytesToRead) {
    int nNumberOfBytesRead = 0;
    ppszError = malloc(sizeof(char *));

    nNumberOfBytesRead = read((int)hPort, pBuffer, nNumberOfBytesToRead);
    if (nNumberOfBytesRead < 0) {
      if (errno == EAGAIN) {
	return 0;
      }

      *ppszError = getLastErrorMsg("read failed");
      return -1;
    }

    *ppszError = NULL;
    return nNumberOfBytesRead;
}
long writeToPort(char** ppszError, long hPort, char* pBuffer,
                 long nNumberOfBytesToWrite) {
    int nNumberOfBytesWritten = 0;
    ppszError = malloc(sizeof(char *));


    nNumberOfBytesWritten = write((int)hPort, pBuffer, nNumberOfBytesToWrite);
    if (nNumberOfBytesWritten < 0) {
        if (errno == EAGAIN) {
            return 0;
        }

        *ppszError = getLastErrorMsg("write failed");
        return -1;
    }

    *ppszError = NULL;
    return nNumberOfBytesWritten;
}
Пример #13
0
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits){
	m_colorBits = colorBits;
	m_depthBits = depthBits;
	m_stencilBits = stencilBits;

	//Set8087CW($133F);
	dch = GetDC(GetActiveWindow());
	assert(dch!=NULL);

	setupDeviceContext();

	glch= wglCreateContext(dch);
	if(glch==NULL){
		std::stringstream msg;
		msg << "wglCreateContext() failed.\n" << getLastErrorMsg();
		throw runtime_error(msg.str());
	}
	makeCurrent();

	GLint glewErr = glewInit();
	if (glewErr != GLEW_OK) {
		throw runtime_error(string("Error initialising Glew: ") + (char*)glewGetErrorString(glewErr));
	}
}
/**
 * CSymbianTransportAgent::sendMessage()
 */
char* CSymbianTransportAgent::sendMessage(const char* msg)
{
    LOG.debug("entering CSymbianTransportAgent::sendMessage"); 
    
    // Check if user aborted current sync.
    if (getLastErrorCode() == KErrCancel) {
        LOG.debug("Leaving sendMessage - lastErrorCode is %d", getLastErrorCode());
        User::Leave(KErrCancel);    // leave is trapped at SyncActiveObject::RunL().
    }
    
    // Just to be sure the response buffer is ok
    //TO BE VERIFIED!!!!
    delete iResponseBody;
    iResponseBody = NULL; 
    
    // Set the POST body
    delete iPostBody;
    iPostBody = NULL;

    if (url.fullURL == NULL) {
        setErrorF(ERR_CONNECT, "Empty URL"); 
        LOG.error("Transport Agent: empty URL");
        return NULL;
    }

    char* response = NULL;
    RStringF method;
    RHTTPHeaders hdr;
    // Parse string to URI (as defined in RFC2396)
    TUriParser8 uri;
    HBufC8* fullUrl = charToNewBuf8(url.fullURL); 
    TInt parseErr = uri.Parse(*fullUrl);
    if (parseErr != KErrNone) {
        setErrorF(ERR_CONNECT, "Malformed URL"); 
        LOG.error("Transport Agent: malformed url");
        goto finally;
    }

    {
        TPtrC8 ptr(reinterpret_cast<const TUint8*>(msg));
        iPostBody = HBufC8::NewL(ptr.Length());
        iPostBody->Des().Copy(ptr);
    }
    
    FConnection* connection = FConnection::getInstance();
    if (connection->isConnected() == false) {
        int res = connection->startConnection();
        if (res) {
            setErrorF(ERR_CONNECT, "Connection error (%d): please check your internet settings.", res); 
            LOG.error("%s", getLastErrorMsg());
            goto finally;
        }
    }

    // Get request method string for HTTP POST
    method = iHttpSession.StringPool().StringF( HTTP::EPOST, RHTTPSession::GetTable());

    // Open transaction with previous method and parsed uri. This class will 
    // receive transaction events in MHFRunL and MHFRunError.
    iHttpTransaction = iHttpSession.OpenTransactionL( uri, *this, method );

    // Set headers for request; user agent, accepted content type and body's 
    // content type.
    hdr = iHttpTransaction.Request().GetHeaderCollection();
    SetHeaderL(hdr, HTTP::EUserAgent, _L8("Funambol Symbian SyncML client"));
    SetHeaderL(hdr, HTTP::EAccept, _L8("*/*"));
    SetHeaderL(hdr, HTTP::EContentType, _L8("application/vnd.syncml+xml"));

    LOG.debug("Sending message:");
    LOG.debug("%s", msg);

    // Set data supplier for POST body
    // Please see  » Symbian OS v9.1 » Symbian OS guide » Using HTTP Client »
    // Handling request body data for explanation on this part
    iDataSupplier = this;
    iHttpTransaction.Request().SetBody(*iDataSupplier);     

    // Submit the transaction. After this the framework will give transaction
    // events via MHFRunL and MHFRunError.
    iHttpTransaction.SubmitL();

    // Start the scheduler, once the transaction completes or is cancelled on an
    // error the scheduler will be stopped in the event handler
    // This is a trick to implement a synchronous method
    LOG.debug("starting ASync scheduler...");
    iASWait->Start();  // TO BE VERIFIED!!!!
    LOG.debug("ASync scheduler stopped");
    
    
    // Check if user aborted current sync.
    if (getLastErrorCode() == KErrCancel) {
        LOG.debug("Leaving sendMessage - lastErrorCode is %d", getLastErrorCode());
        User::Leave(KErrCancel);    // leave is trapped at SyncActiveObject::RunL().
    }
    
    // when all is finished, return char* to be delete []
    if(!iTransFailed) {
        TInt length = iResponseBody->Des().Length();
        response = new char[length+1];
        Mem::Copy(response, iResponseBody->Ptr(), length);
        response[length] = '\0';

        LOG.debug("Message received:");
        LOG.debug("%s", response);
    }
    else {
        LOG.debug("HTTP transaction failed");
        setErrorF(ERR_HTTP, "HTTP request error: request timed out waiting for response");
    }

finally:

    // Transaction can be closed now. It's not needed anymore.
    LOG.debug("closing HTTP transaction");
    iHttpTransaction.Close();

    delete fullUrl;
    LOG.debug("exiting CSymbianTransportAgent::sendMessage");
    return response;
}
void configurePort(char** ppszError, int hPort, long baudRate,
                          unsigned long options) {

    struct termios attributes;
    speed_t speed;
    int linesToSet;
    int flgs;

    memset(&attributes, 0, sizeof (attributes));
    attributes.c_cflag = CREAD | HUPCL | CLOCAL;

    switch(baudRate) {
    case 50:
        speed = B50;
        break;

    case 75:
        speed = B75;
        break;

    case 110:
        speed = B110;
        break;

    case 134:
        speed = B134;
        break;

    case 150:
        speed = B150;
        break;

    case 200:
        speed = B200;
        break;

    case 300:
        speed = B300;
        break;

    case 600:
        speed = B600;
        break;

    case 1200:
        speed = B1200;
        break;

    case 1800:
        speed = B1800;
        break;

    case 2400:
        speed = B2400;
        break;

    case 4800:
        speed = B4800;
        break;

    case 9600:
        speed = B9600;
        break;

    case 19200:
        speed = B19200;
        break;

    case 38400:
        speed = B38400;
        break;

    case 57600:
        speed = B57600;
        break;

    case 115200:
        speed = B115200;
        break;

    default:
        *ppszError = COMM_BAD_BAUDRATE;
        return;
    }
    cfsetispeed(&attributes, speed);
    cfsetospeed(&attributes, speed);


    /* default no parity */
    if (options & ODD_PARITY) {
        attributes.c_cflag |= PARENB | PARODD;
    } else if (options & EVEN_PARITY) {
        attributes.c_cflag |= PARENB;
    }


    /* CTS output flow control */
    if (options & AUTO_CTS) {
        attributes.c_cflag |= CRTSCTS;
    }

/*  The following is not supported by Linux */
#ifndef LINUX
    /* RTS flow control */
    if (options & AUTO_RTS) {
        /***attributes.c_cflag |= CRTSXOFF;***/
    }
#endif

    /* BITS_PER_CHAR_8 is 2 bits and includes BITS_PER_CHAR_7 */
    if ((options & BITS_PER_CHAR_8) == BITS_PER_CHAR_8) {
        attributes.c_cflag |= CS8;
    } else {
        attributes.c_cflag |= CS7;
    }

    /* default 1 stop bit */
    if (options & STOP_BITS_2) {
        attributes.c_cflag |= CSTOPB;
    }


    /* set blocking since we are not using async methods */
    flgs = fcntl(hPort, F_GETFL, 0);
    //    fcntl(hPort, F_SETFL, flgs | O_NONBLOCK);

    /* block for at least 1 character, but wait .1 secs */
    attributes.c_cc[VMIN] = 1;
    attributes.c_cc[VTIME] = 0;

    if (tcsetattr(hPort, TCSANOW, &attributes) == -1) {
      ppszError = malloc(sizeof(char *));
      *ppszError = getLastErrorMsg("set attr failed");
      return;
    }


    /* Make sure the Data Terminal Ready line is on */
    linesToSet = TIOCM_DTR;
    ioctl(hPort, TIOCMBIS, &linesToSet);


    *ppszError = NULL;

}
Пример #16
0
int HttpConnection::sendData(const char* data, int data_len)
{
    int totalBytesRead = 0;
    int ret = 0;
    DWORD bytesWritten = 0;
    DWORD errorCode = 0;

    if (!InternetWriteFile(req, data, data_len, &bytesWritten)) {
        errorCode = GetLastError();

        char* tmp = createHttpErrorMessage(errorCode);
        setErrorF(errorCode, "InternetWriteFile error %d: %s", errorCode, tmp);
        LOG.info("%s", getLastErrorMsg());
        delete [] tmp; tmp = NULL;
        //
        // The certificate is not trusted. Send the right error code to the
        // client
        //
        if (errorCode == ERROR_INTERNET_INVALID_CA) {
            setError(ERR_HTTPS_INVALID_CA, "The certificate is invalid");
            LOG.error("%s", getLastErrorMsg());

            // try to understand a bit more on the certificate
            INTERNET_CERTIFICATE_INFO   certificateInfo;
            DWORD                       certInfoLength = sizeof(INTERNET_CERTIFICATE_INFO);                
            if (TRUE == InternetQueryOption(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, 
                &certificateInfo, &certInfoLength)) {

                    char* subj   = (char*)certificateInfo.lpszSubjectInfo;
                    char* issuer = (char*)certificateInfo.lpszIssuerInfo;    
                    LOG.debug("Cert Subject %s", subj);
                    LOG.debug("Cert Issuer %s",  issuer);

            } else {                        
                LOG.debug("Cannot retrieve info about the certificate");
            }     
        } else if (errorCode == ERROR_INTERNET_OFFLINE_MODE) {                     // 00002 -> retry
            LOG.debug("Offline mode detected: go-online and retry...");
            WCHAR* wurl = toWideChar(url.fullURL);
            InternetGoOnline(wurl, NULL, NULL);
            delete [] wurl;
        } else if (errorCode == ERROR_INTERNET_TIMEOUT ||                     // 12002 -> out code 2007
            errorCode == ERROR_INTERNET_INCORRECT_HANDLE_STATE) {      // 12019 -> out code 2007
                setError(ERR_HTTP_TIME_OUT, "Network error: the request has timed out -> exit.");
                LOG.debug("%s", getLastErrorMsg());
        } else if (errorCode == ERROR_INTERNET_CANNOT_CONNECT) {              // 12029 -> out code 2001
            setError(ERR_CONNECT, "Network error: the attempt to connect to the server failed -> exit"); 
            LOG.debug("%s", getLastErrorMsg());
        }
        // Other network error: retry.
        LOG.info("Network error writing data from client");
        resetError();
    }

    if (bytesWritten != data_len) {
        LOG.error("[%s] Warning: possible loss of data: %d bytes read, %d bytes written", 
            __FUNCTION__, data_len, bytesWritten);
    }

    return errorCode;
}
Пример #17
0
/*
* Used to start the sync process. The argument is an array of SyncSources
* that have to be synched with the sync process
*/
int SyncClient::sync(AbstractSyncConfig& config, SyncSource** sources) {

    resetError();
    int ret = 0;

    if (!config.getAbstractSyncSourceConfigsCount()) {
        //sprintf(lastErrorMsg, "Error in sync() - configuration not set correctly.");
        ret = 1;
        setError(ret, "Error in sync() - configuration not set correctly.");
        
        LOG.error("%s", getLastErrorMsg());
        return ret;
    }

    //
    // Synchronization report.
    //
    syncReport.setSyncSourceReports(config);
    // Set source report on each SyncSource (assign pointer)
    int i=0;
    while (sources[i]) {
        char* name = toMultibyte(sources[i]->getName());
        SyncSourceReport *ssr = syncReport.getSyncSourceReport(name);
        ssr->setState(SOURCE_ACTIVE);
        sources[i]->setReport(ssr);

        delete[] name;
        i++;
    }

    SyncManager syncManager(config, syncReport);

    if ((ret = syncManager.prepareSync(sources))) {
        LOG.error("Error in preparing sync: %s", getLastErrorMsg());
        goto finally;
    }

    ret = continueAfterPrepareSync();
    if (ret) {
        LOG.error("SyncClient: continueAfterPrepareSync returns error code: %d.", ret);
        goto finally;
    }

    if ((ret = syncManager.sync())) {
        LOG.error("Error in syncing: %s", getLastErrorMsg());
        goto finally;
    }

    ret = continueAfterSync();
    if (ret) {
        LOG.error("SyncClient: continueAfterSync returns error code: %d.", ret);
        goto finally;
    }

    if ((ret = syncManager.endSync())) {
        LOG.error("Error in ending sync: %s", getLastErrorMsg());
        goto finally;
    }

finally:

    // Update SyncReport with last error from sync
    syncReport.setLastErrorCode(getLastErrorCode());
    syncReport.setLastErrorMsg(getLastErrorMsg());

    return ret;
}
/*
 * Sends the given SyncML message to the server specified
 * by the instal property 'url'. Returns the response status code or -1
 * if it was not possible initialize the connection.
 *
 * Use getResponse() to get the server response.
 */
char* CurlTransportAgent::sendMessage(const char* msg) {
    if (!easyhandle) {
        setError(ERR_NETWORK_INIT, "libcurl error init error");
        LOG.error("%s", getLastErrorMsg());
        return NULL;
    }

    size_t size = strlen(msg);


    LOG.debug("Requesting resource %s at %s:%d", url.resource, url.host, url.port);
    POSIX_LOG.setPrefix("data out: ");
    LOG.debug("=== %d bytes ===\n%s", (int)size, msg);
    POSIX_LOG.setPrefix(NULL);

    curl_slist *slist=NULL;
    char *response = NULL;
    CURLcode code;
    char contenttype[256];
    sprintf(contenttype, "Content-Type: %s", SYNCML_CONTENT_TYPE);
    slist = curl_slist_append(slist, contenttype);
    // Disable "Expect: 100": it is usually used to check without
    // transmitting the data that the recipient is willing to accept
    // the POST . With SyncML servers that should be the case, so the
    // check just adds one round-trip and worse, "Expect: 100" is not
    // supported by some proxies, causing a complete failure.
    slist = curl_slist_append(slist, "Expect:");
    responsebuffersize = 64 * 1024;
    responsebuffer = new char[responsebuffersize];
    received = 0;
    responsebuffer[0] = 0;
    // todo? url.resource
    const char *certificates = getSSLServerCertificates();
    if ((code = curl_easy_setopt(easyhandle, CURLOPT_POST, true)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_URL, url.fullURL)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, msg)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, size)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, slist)) ||
        /*
         * slightly cheating here: when CURLOPT_CAINFO was set before, we don't unset it because
         * we don't know what the default is
         */
        (certificates[0] && (code = curl_easy_setopt(easyhandle, CURLOPT_CAINFO, certificates))) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, (long)SSLVerifyServer)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, (long)(SSLVerifyHost ? 2 : 0))) ||
        (code = curl_easy_perform(easyhandle))) {
        delete [] responsebuffer;
        setErrorF(ERR_HTTP, "libcurl error %d, %.250s", code, curlerrortxt);
        LOG.error("%s", getLastErrorMsg());
    } else {
        response = responsebuffer;

        POSIX_LOG.setPrefix("data in: ");
        LOG.debug("=== %d bytes ===\n%s",
                  (int)strlen(response),
                  response);
    }
    POSIX_LOG.setPrefix(NULL);


    responsebuffer = NULL;
    responsebuffersize = 0;

    if (slist) {
        curl_slist_free_all(slist);
    }

    return response;
}
void DeviceManagementNode::update(bool read) 
{
    if (!read && !modified) {
        // no work to be done
        return;
    }

    StringBuffer fileName(currentDir);
    concatDirs(fileName, configFile.c_str());
    const char* fname = fileName.c_str();
    FILE* file = fopen(fname, "r");
    
    if (!file) {
        // Maybe the file or directory does not exist: create it and try again.
        LOG.debug("Could not open file, create it empty: '%s'", fileName.c_str());
        mkdirAll(currentDir);
        file = fopen(fname, "w+");  // "w+" to create the file and be able to read/write
        
        // Anyway, set the last error so Clients can know the file was not found.
        setErrorF(ERR_DM_TREE_NOT_AVAILABLE, "File not found: '%s'", fileName.c_str());
    }

    if (file) {
        // Open a temp file in writing mode if we must update the config
        if (!read) {
            fclose(file);
            fileName.append(".tmp");
            file = fopen(fileName, "w");
            if (!file) {
                setErrorF(ERR_INVALID_CONTEXT, "Error opening file: '%s'", fileName.c_str());
                LOG.error("%s", getLastErrorMsg());
                return;
            }
        }

        if (read) {
            // Note: don't create local buffers too big, the Symbian stack size is limited!
            char buffer[128];

            lines->clear();
            while (fgets(buffer, sizeof(buffer), file)) {
                char *eol = strchr(buffer, '\r');
                if (!eol) {
                    eol = strchr(buffer, '\n');
                }
                if (eol) {
                    *eol = 0;
                }
                line newline(buffer);
                lines->add(newline);
            }
            fclose(file);
        } 
        else {
            int i = 0;
            while (true) {
                line *curr = (line *)lines->get(i);
                if (!curr) {
                    break;
                }
                fprintf(file, "%s\n", curr->getLine());

                i++;
            }
            fflush(file);
            if (!ferror(file)) {
                StringBuffer tmpConfig(configFile);
                tmpConfig += ".tmp";

                // Both files must be closed for the rename.
                int ret = fclose(file);
                if (ret) {
                    setErrorF(ret, "Error (%d) closing file: '%s'", ret, fileName.c_str());
                    return;
                }

                renameFileInCwd( tmpConfig.c_str(), configFile.c_str());
            }
            else {
                fclose(file);
            }
        }
    }
    else {
        setErrorF(ERR_DM_TREE_NOT_AVAILABLE, "Error opening file: '%s'", fileName.c_str());
        LOG.error("%s", getLastErrorMsg());
        return;
    }
}