context: /***************************************************************************************************************************************
   * Copyright (C) 2001-2012 LearnLift USA																	*
   * Contact: Learnlift USA, 12 Greenway Plaza, Suite 1510, Houston, Texas 77046, support@memorylifter.com					*
   *																								*
   * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License	*
   * as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.			*
   *																								*
   * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty	*
   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.	*
   *																								*
   * You should have received a copy of the GNU Lesser General Public License along with this library; if not,					*
   * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA					*
   ***************************************************************************************************************************************/
  using System;
  using System.Data;
  using System.Web;
  using System.Collections;
  using System.Web.Services;
  using System.Web.Services.Protocols;
  using System.ComponentModel;
  using System.IO;
  using System.Collections.Generic;
  using System.Net.Mail;
  using System.Configuration;
  using System.Text.RegularExpressions;
  using System.Text;
  
  namespace MLifterWebService
  {
  	/// <summary>
  	/// Summary description for Service1
  	/// </summary>
  	[WebService(Namespace = "http://www.memorylifter.com/ErrorReportService/")]
  	[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  	[ToolboxItem(false)]
  	public class ErrorReportService : System.Web.Services.WebService
  	{
  		private static string LogFile;
  
  		/// <summary>
  		/// Initializes a new instance of the <see cref="ErrorReportService"/> class.
  		/// </summary>
  		/// <remarks>Documented by Dev02, 2009-07-20</remarks>
  		public ErrorReportService()
  		{
  			if (String.IsNullOrEmpty(LogFile))
  				LogFile = Server.MapPath(ConfigurationManager.AppSettings["LogPath"]);
  		}
  		/// <summary>
  		/// Logs the specified message.
  		/// </summary>
  		/// <param name="message">The message.</param>
  		/// <remarks>Documented by Dev02, 2009-07-20</remarks>
  		public static void Log(string message)
  		{
  			string line = Environment.NewLine + DateTime.Now.ToLongTimeString() + ": ";
  			File.AppendAllText(LogFile, line + message);
  		}
  
  		/// <summary>
  		/// Starts a new Error Report Transfer.
  		/// </summary>
  		/// <param name="filename">The filename.</param>
  		/// <param name="filesize">The filesize.</param>
  		/// <param name="chunksize">The chunksize.</param>
  		/// <returns>True, if successful, else false.</returns>
  		/// <remarks>Documented by Dev02, 2007-11-19</remarks>
  		[WebMethod(Description = "Starts a new Error Report Transfer", EnableSession = true)]
  		public bool TransferStart(string filename, int filesize, int chunksize, string sender, string senderMessage, string stackTrace)
  		{
  			int chunkLimit = Convert.ToInt32(ConfigurationManager.AppSettings["ChunkSizeLimit"]) * 1024;
  			int sizeLimit = Convert.ToInt32(ConfigurationManager.AppSettings["MaxSizeLimit"]) * 1024;
  			if (filesize < sizeLimit && chunksize < chunkLimit && !string.IsNullOrEmpty(filename) && filesize > 0 && chunksize > 0)
  			{
  				ErrorReport report = new ErrorReport();
  				report.FileName = Path.GetFileName(filename);
  				report.FileSize = filesize;
  				report.ChunkSize = chunksize;
  				report.PartCount = Convert.ToInt32(Math.Ceiling(filesize * 1.0 / chunksize));
  				report.Sender = sender;
  
  				report.Message = senderMessage;
  				report.StackTrace = stackTrace;
  
  				Session[filename] = report;
  				return true;
  			}
  			else
  				return false;
  		}
  
  		/// <summary>
  		/// Transfers a Data Chunk to the server.
  		/// </summary>
  		/// <param name="filename">The filename.</param>
  		/// <param name="content">The content.</param>
  		/// <param name="partcount">The partcount.</param>
  		/// <returns>True, if successful, else false.</returns>
  		/// <remarks>Documented by Dev02, 2007-11-19</remarks>
  		[WebMethod(Description = "Transfers a Data Chunk to the server", EnableSession = true)]
  		public bool TransferChunk(string filename, byte[] content, int partcount)
  		{
  			ErrorReport report;
  			if (Session[filename] == null || (report = Session[filename] as ErrorReport) == null)
  				return false;
  			//check session
  			if (filename == new FileInfo(report.FileName).Name && partcount == report.PartCount && content.Length <= report.ChunkSize && report.DataChunks.Count < report.PartCount)
  			{
  				report.DataChunks.Add(content);
  				return true;
  			}
  			else
  				return false;
  
  		}
  
  		/// <summary>
  		/// Finishes an Error Report Transfer.
  		/// </summary>
  		/// <param name="filename">The filename.</param>
  		/// <param name="partcount">The partcount.</param>
  		/// <returns>True, if successful, else false.</returns>
  		/// <remarks>Documented by Dev02, 2007-11-19</remarks>
  		[WebMethod(Description = "Finishes an Error Report Transfer", EnableSession = true)]
  		public bool TransferFinish(string filename, int partcount)
  		{
  			ErrorReport report;
  			if (Session[filename] == null || (report = Session[filename] as ErrorReport) == null)
  				return false;
  			//check session
  			if (filename == new FileInfo(report.FileName).Name && partcount == report.PartCount && partcount == report.DataChunks.Count)
  			{
  				try
  				{
  					SendEmail(report);
  					return true;
  				}
  				catch
  				{
  					return false;
  				}
  				finally
  				{
  					Session.Clear();
  				}
  			}
  			else
  				return false;
  		}
  
  		/// <summary>
  		/// Internally used error container object.
  		/// </summary>
  		class ErrorReport
  		{
  			/// <summary>
  			/// The file name
  			/// </summary>
  			public string FileName { get; set; }
  			/// <summary>
  			/// The file size
  			/// </summary>
  			public int FileSize { get; set; }
  			/// <summary>
  			/// The chunk size
  			/// </summary>
  			public int ChunkSize { get; set; }
  			/// <summary>
  			/// The number of parts/chunks
  			/// </summary>
  			public int PartCount { get; set; }
  			/// <summary>
  			/// The data chunks
  			/// </summary>
  			public List<byte[]> DataChunks { get; set; }
  			/// <summary>
  			/// The sender email address
  			/// </summary>
  			public string Sender { get; set; }
  			/// <summary>
  			/// The senders message
  			/// </summary>
  			public string Message { get; set; }
  			/// <summary>
  			/// The stack trace
  			/// </summary>
  			public string StackTrace { get; set; }
  
  			/// <summary>
  			/// Constructor
  			/// </summary>
  			public ErrorReport()
  			{
  				DataChunks = new List<byte[]>();
  			}
  		}
  
  
  		/// <summary>
  		/// Class for grabbing the error report information from the filename of the zip file.
  		/// </summary>
  		/// <remarks>Documented by Dev09, 2009-07-16</remarks>
  		class ReportInformation
  		{
  			public string Date = DateTime.Today.ToShortDateString();
  			public string Time = DateTime.Now.ToShortTimeString();
  			public string MLVersion = "-";
  
  			public ReportInformation(string filename)
  			{
  				Match m = Regex.Match(filename, @"^MemoryLifter_ErrorReport_(.+)_(.+)_(.+)\.zip$");
  
  				if (m.Success)
  				{
  					string tdate = m.Groups[1].ToString();
  					string ttime = m.Groups[2].ToString();
  					string tversion = m.Groups[3].ToString();
  					Match d = Regex.Match(tdate, @"(\d{4})-(\d{2})-(\d{2})");
  
  					if (d.Success)
  					{
  						string year = d.Groups[1].ToString();
  
gt: 						string month = d.Groups[2].ToString();