// // NtpConfMapper.cs // // Author: // Carsten Sonne Larsen // // Copyright (c) 2013 Carsten Sonne Larsen // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using Ntp.Analyzer.Log; using Ntp.Analyzer.Objects; using Ntp.Data; namespace Ntp.Analyzer.Data.File { public sealed class NtpConfMapper : DataMapper { private readonly string file; private List entries; private TextReader reader; private readonly Object locker = new Object (); public NtpConfMapper (string file, LogBase log) : base (log) { this.file = file; } /// /// Read all data from file in a sequential manner. /// /// The enumerator. public override IEnumerator GetEnumerator () { lock (locker) { Import (); return entries.GetEnumerator (); } } private void Import () { if (entries != null) return; entries = new List (); lock (entries) { if (file == null) throw new ArgumentException ("No filename specified for import file."); try { reader = new StreamReader (file); while (reader.Peek () != -1) { string line = reader.ReadLine (); if (line != null && line.Trim () == String.Empty) continue; NtpConfEntry entry = ParseLine (line); if (entry != null) entries.Add (entry); } } finally { if (reader != null) reader.Close (); } } } private NtpConfEntry ParseLine (string line) { string l = line.Trim () + String.Empty.PadLeft (10); // Find server role TimeServerRole role; if (l.Substring (0, 4) == "peer") { role = TimeServerRole.Peer; l = l.Remove (0, 4); } else if (l.Substring (0, 6) == "server") { role = TimeServerRole.Server; l = l.Remove (0, 6); } else return null; // Find address l = l.Trim (); int addressPos = l.IndexOf (" ", StringComparison.Ordinal); string address = l.Substring (0, addressPos); string name = address; IPAddress ip; IPAddress.TryParse (address, out ip); // Find hostname if (ip == null) { try { ip = Dns.GetHostAddresses (address) [0]; } catch (Exception exception) { Debug.WriteLine (exception); return null; } } else { try { IPHostEntry hostEntry = Dns.GetHostEntry (ip); name = hostEntry.HostName; } catch (Exception exception) { Debug.WriteLine (exception); return null; } } // Find org id int? orgId = null; int orgPos = l.IndexOf ("#", StringComparison.Ordinal); if (orgPos != -1) { string org = l.Substring (orgPos + 1).Trim (); orgPos = org.IndexOf (" ", StringComparison.Ordinal); org = org.Substring (0, orgPos).Trim (); int realOrgId; // Nullable not fully supported by NTP Analyzer. if (!Int32.TryParse (org, out realOrgId)) return null; orgId = realOrgId; } return new NtpConfEntry (role, ip, name, orgId); } } }