--- /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 <f32file.h> // RFs
+#include <in_sock.h> // 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
+}
+