diff -r 000000000000 -r af10295192d8 tcpiputils/dnd/src/hosts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tcpiputils/dnd/src/hosts.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,353 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// hosts.cpp - name resolver hosts file parser module +// + +#include // RFs +#include // TInetAddr +#include "hosts.h" // this + +RHostsFile::RHostsFile(RFs &aFs): + iBuf(NULL), iFs(aFs), iRefreshed(0) +{ +} + +RHostsFile::~RHostsFile() +{ + if (iBuf) + { + delete iBuf; + iBuf = NULL; + } +} + +// +// +// + +TInt RHostsFile::Open() +{ + if (iBuf) + { + return KErrNone; + } + + const TDesC &file_name = HOSTS_FILE; + TInt err; + + RFile file; + err = file.Open(iFs, file_name, EFileStreamText | EFileRead | EFileShareAny); + + if (err != KErrNone) + { + return err; + } + + TInt size; + err = file.Size(size); + + if (err != KErrNone) + { + file.Close(); + return err; + } + + iBuf = HBufC::NewMax(size); + + if (iBuf == NULL) + { + file.Close(); + return KErrNoMemory; + } + + // Unicode fix. + + HBufC8 *tempBuf = HBufC8::NewMax(size); + + if (tempBuf == NULL) + { + delete iBuf; + iBuf = NULL; + file.Close(); + return KErrNoMemory; + } + + TPtr8 tempPtr(tempBuf->Des()); + err = file.Read(tempPtr); + + if (err != KErrNone) + { + delete iBuf; + delete tempBuf; + iBuf = NULL; + file.Close(); + return err; + } + + TPtr p(iBuf->Des()); + p.Copy(tempPtr); + delete tempBuf; + + iCharLex = p; + file.Close(); + + return KErrNone; +} + +void RHostsFile::Close() +{ + delete iBuf; + iBuf = NULL; +} + +// +// +// + +TInt RHostsFile::ReadLn(TPtrC& aLine) +{ + do + { + iCharLex.Mark(); + + if (iCharLex.Eos()) + { + return KErrEof; + } + + TChar ch = 0; + + while (!iCharLex.Eos() && (ch = iCharLex.Peek(), ch != '\n' && ch != '\r' && ch != '#' )) + { + iCharLex.Inc(); + } + + aLine.Set(iCharLex.MarkedToken()); + + if (ch == '#') + { + while (!iCharLex.Eos() && (ch = iCharLex.Peek(), ch != '\n' && ch != '\r')) + { + iCharLex.Inc(); + } + } + + while (!iCharLex.Eos() && (ch = iCharLex.Peek(), ch == '\n' || ch == '\r')) + { + iCharLex.Inc(); + } + } + while (!aLine.Length()); + + return KErrNone; +} + + +void RHostsFile::Rewind() +{ + if (iBuf) + { + TPtr p(iBuf->Des()); + iCharLex = p; + } +} + +void RHostsFile::Refresh() + { + const TDesC &file_name = HOSTS_FILE; + TInt err; + + TTime modified; + err = iFs.Modified(file_name, modified); + + if (err == KErrNone) + { + if (iRefreshed < modified) + { + Close(); + Open(); + iRefreshed = modified; + return; + } + } + Rewind(); + } + +// +// +// + +void RHostsFile::GetByName(TNameRecord& aResult, TRequestStatus& err) +{ + Refresh(); + TInt count = 0; // ...to select correct result for Next() + + for (;;) + { + TPtrC line; + err = ReadLn(line); + + if (err != KErrNone) + { + if (err == KErrEof) + { + err = KErrNotFound; + } + return; + } + + TLex wordLex(line); + TInetAddr addr; + TPtrC word; + + word.Set(wordLex.NextToken()); + err = addr.Input(word); + + if (err != KErrNone) + { + return; + } + + TPtrC name; + name.Set(wordLex.NextToken()); + + if (!name.Length()) + { + err = KErrBadName; + return; + } + + err = KErrNotFound; + + if (name.CompareF(aResult.iName) == 0 && ++count > aResult.iFlags) + { + err = KErrNone; + } + else + { + TPtrC alias; + + for ( + alias.Set(wordLex.NextToken()); + alias.Length(); + alias.Set(wordLex.NextToken()) + ){ + if (alias.CompareF(aResult.iName) == 0 && ++count > aResult.iFlags) + { + err = KErrNone; + break; + } + } + } + + if (err == KErrNone) + { + aResult.iAddr = addr; + aResult.iName = name; + return; + } + } +} + +void RHostsFile::GetByAddress(TNameRecord& aResult, TRequestStatus& err) +{ +#if 1 + const TInt ipv6 = (aResult.iAddr.Family() == KAfInet6); + const TUint32 scope = TInetAddr::Cast(aResult.iAddr).Scope(); +#endif + Refresh(); + + TInt count = 0; // ...to select correct result for Next() + for (;;) + { + TPtrC line; + err = ReadLn(line); + + if (err != KErrNone) + { + if (err == KErrEof) + { + err = KErrNotFound; + } + return; + } + + TLex wordLex(line); + TInetAddr addr; + + TPtrC word; + word.Set(wordLex.NextToken()); + err = addr.Input(word); + + if (err != KErrNone) + { + return; + } +#if 0 + if (!addr.CmpAddr(aResult().iAddr)) + { + continue; + } +#else + // Plain IPv4 addresses in hosts will match the same + // address in IPv4mapped format. However, IPv4 mapped + // in hosts file will not match plain IPv4, if queried + if (ipv6 && addr.Family() == KAfInet) + addr.ConvertToV4Mapped(); + // ... if the hosts file specifies the scope, + // require it to match too. + if (!addr.Match(aResult.iAddr) || + (addr.Scope() != 0 && addr.Scope() != scope)) + { + continue; + } +#endif + TPtrC name; + name.Set(wordLex.NextToken()); + while (name.Length() > 0) + { + if (++count > aResult.iFlags) + { + aResult.iAddr = addr; + aResult.iName = name; + err = KErrNone; + return; + } + name.Set(wordLex.NextToken()); + } + err = count == 0 ? KErrBadName : KErrNotFound; + return; + } +} + +void RHostsFile::Next(TNameRecord& /* aResult */, TRequestStatus& err) +{ +#if 0 + TPtrC alias; + alias.Set(iWordLex.NextToken()); + + if (!alias.Length()) + { + err = KErrNotFound; + return; + } + + aResult.iName = alias; + err = KErrNone; +#else + // Next() is not used now + err = KErrNotFound; +#endif +} +