2207 lines
46 KiB
C#
2207 lines
46 KiB
C#
// CoreUtil
|
|
//
|
|
// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
|
|
// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
|
|
// Comments: Tetsuo Sugiyama, Ph.D.
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// version 2 as published by the Free Software Foundation.
|
|
//
|
|
// This program 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License version 2
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
//
|
|
// 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.
|
|
//
|
|
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
|
|
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
|
|
//
|
|
//
|
|
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
|
|
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
|
|
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
|
|
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
|
|
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
|
|
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
|
|
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
|
|
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
|
|
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
|
|
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
|
|
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
|
|
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
|
|
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
|
|
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
|
|
//
|
|
// USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS
|
|
// YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY
|
|
// CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS
|
|
// SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE
|
|
// SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO
|
|
// COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING
|
|
// PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR
|
|
// CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE
|
|
// NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
|
|
// INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+
|
|
// COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE
|
|
// WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY
|
|
// COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE
|
|
// COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE
|
|
// SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR
|
|
// COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO
|
|
// RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
|
|
// RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT
|
|
// JUST A STATEMENT FOR WARNING AND DISCLAIMER.
|
|
//
|
|
//
|
|
// SOURCE CODE CONTRIBUTION
|
|
// ------------------------
|
|
//
|
|
// Your contribution to SoftEther VPN Project is much appreciated.
|
|
// Please send patches to us through GitHub.
|
|
// Read the SoftEther VPN Patch Acceptance Policy in advance:
|
|
// http://www.softether.org/5-download/src/9.patch
|
|
//
|
|
//
|
|
// DEAR SECURITY EXPERTS
|
|
// ---------------------
|
|
//
|
|
// If you find a bug or a security vulnerability please kindly inform us
|
|
// about the problem immediately so that we can fix the security problem
|
|
// to protect a lot of users around the world as soon as possible.
|
|
//
|
|
// Our e-mail address for security reports is:
|
|
// softether-vpn-security [at] softether.org
|
|
//
|
|
// Please note that the above e-mail address is not a technical support
|
|
// inquiry address. If you need technical assistance, please visit
|
|
// http://www.softether.org/ and ask your question on the users forum.
|
|
//
|
|
// Thank you for your cooperation.
|
|
//
|
|
//
|
|
// NO MEMORY OR RESOURCE LEAKS
|
|
// ---------------------------
|
|
//
|
|
// The memory-leaks and resource-leaks verification under the stress
|
|
// test has been passed before release this source code.
|
|
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Data;
|
|
using System.Data.Sql;
|
|
using System.Data.SqlClient;
|
|
using System.Data.SqlTypes;
|
|
using System.Text;
|
|
using System.Configuration;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using System.Web;
|
|
using System.Web.Security;
|
|
using System.Web.UI;
|
|
using System.Web.UI.WebControls;
|
|
using System.Web.UI.WebControls.WebParts;
|
|
using System.Web.UI.HtmlControls;
|
|
using System.IO;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Web.Mail;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
|
|
#if ASPNET
|
|
using Resources.BuildUtil.Properties;
|
|
#else
|
|
using BuildUtil.Properties;
|
|
#endif
|
|
|
|
namespace CoreUtil
|
|
{
|
|
public static class Con
|
|
{
|
|
static ConsoleService cs = null;
|
|
|
|
public static ConsoleService ConsoleService
|
|
{
|
|
get { return Con.cs; }
|
|
}
|
|
|
|
public static void SetConsoleService(ConsoleService svc)
|
|
{
|
|
cs = svc;
|
|
}
|
|
|
|
public static void UnsetConsoleService()
|
|
{
|
|
cs = null;
|
|
}
|
|
|
|
public static string ReadLine()
|
|
{
|
|
return ReadLine("");
|
|
}
|
|
public static string ReadLine(string prompt)
|
|
{
|
|
return ReadLine(prompt, false);
|
|
}
|
|
public static string ReadLine(string prompt, bool noFile)
|
|
{
|
|
if (cs != null)
|
|
{
|
|
return cs.ReadLine(prompt, noFile);
|
|
}
|
|
else
|
|
{
|
|
Console.Write(prompt);
|
|
return Console.ReadLine();
|
|
}
|
|
}
|
|
|
|
public static void WriteLine()
|
|
{
|
|
WriteLine("");
|
|
}
|
|
|
|
public static void WriteLine(object arg)
|
|
{
|
|
if (cs != null)
|
|
{
|
|
cs.WriteLine(arg);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(arg);
|
|
}
|
|
}
|
|
|
|
public static void WriteLine(string str)
|
|
{
|
|
if (cs != null)
|
|
{
|
|
cs.WriteLine(str);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(str);
|
|
}
|
|
}
|
|
|
|
public static void WriteLine(string str, object arg)
|
|
{
|
|
if (cs != null)
|
|
{
|
|
cs.WriteLine(str, arg);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(str, arg);
|
|
}
|
|
}
|
|
|
|
public static void WriteLine(string str, params object[] args)
|
|
{
|
|
if (cs != null)
|
|
{
|
|
cs.WriteLine(str, args);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(str, args);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ConsoleUserCancelException : Exception
|
|
{
|
|
public ConsoleUserCancelException(string msg)
|
|
: base(msg)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class ConsoleEvalMinMaxParam
|
|
{
|
|
public readonly string ErrorMessageString;
|
|
public readonly int MinValue, MaxValue;
|
|
|
|
public ConsoleEvalMinMaxParam(string errorMessageString, int minValue, int maxValue)
|
|
{
|
|
this.ErrorMessageString = errorMessageString;
|
|
this.MinValue = minValue;
|
|
this.MaxValue = maxValue;
|
|
}
|
|
}
|
|
|
|
public enum ConsoleType
|
|
{
|
|
Local,
|
|
Csv,
|
|
}
|
|
|
|
public class ConsoleParam
|
|
{
|
|
public readonly string Name;
|
|
public readonly ConsolePromptProcDelegate PromptProc;
|
|
public readonly object PromptProcParam;
|
|
public readonly ConsoleEvalProcDelegate EvalProc;
|
|
public readonly object EvalProcParam;
|
|
internal string Tmp = null;
|
|
public ConsoleParam(string name)
|
|
: this(name, null, null)
|
|
{
|
|
}
|
|
public ConsoleParam(string name,
|
|
ConsolePromptProcDelegate promptProc,
|
|
object promptProcParam)
|
|
: this(name, promptProc, promptProcParam, null, null)
|
|
{
|
|
}
|
|
public ConsoleParam(string name,
|
|
ConsolePromptProcDelegate promptProc,
|
|
object promptProcParam,
|
|
ConsoleEvalProcDelegate evalProc,
|
|
object evalProcParam)
|
|
{
|
|
this.Name = name;
|
|
this.PromptProc = promptProc;
|
|
this.PromptProcParam = promptProcParam;
|
|
this.EvalProc = evalProc;
|
|
this.EvalProcParam = evalProcParam;
|
|
}
|
|
}
|
|
|
|
public delegate string ConsolePromptProcDelegate(ConsoleService c, object param);
|
|
public delegate bool ConsoleEvalProcDelegate(ConsoleService c, string str, object param);
|
|
|
|
delegate void ConsoleFreeDelegate();
|
|
delegate string ConsoleReadLineDelegate(string prompt, bool nofile);
|
|
delegate string ConsoleReadPasswordDelegate(string prompt);
|
|
delegate bool ConsoleWriteDelegate(string str);
|
|
delegate int ConsoleGetWidthDelegate();
|
|
|
|
public class ConsoleParamValueList
|
|
{
|
|
List<ConsoleParamValue> o;
|
|
|
|
public ConsoleParamValueList()
|
|
{
|
|
o = new List<ConsoleParamValue>();
|
|
}
|
|
|
|
public IEnumerable<ConsoleParamValue> Values
|
|
{
|
|
get
|
|
{
|
|
int i;
|
|
for (i = 0; i < o.Count; i++)
|
|
{
|
|
yield return o[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Add(ConsoleParamValue v)
|
|
{
|
|
if (o.Contains(v) == false)
|
|
{
|
|
o.Add(v);
|
|
}
|
|
}
|
|
|
|
public ConsoleParamValue this[string name]
|
|
{
|
|
get
|
|
{
|
|
ConsoleParamValue v = new ConsoleParamValue(name, "", 0);
|
|
|
|
int i = o.IndexOf(v);
|
|
if (i == -1)
|
|
{
|
|
return new ConsoleParamValue(name, "", 0);
|
|
}
|
|
|
|
return o[i];
|
|
}
|
|
}
|
|
|
|
public ConsoleParamValue DefaultParam
|
|
{
|
|
get
|
|
{
|
|
foreach (ConsoleParamValue c in o)
|
|
{
|
|
if (c.IsDefaultParam)
|
|
{
|
|
return c;
|
|
}
|
|
}
|
|
|
|
return new ConsoleParamValue("", "", 0, true);
|
|
}
|
|
}
|
|
|
|
public string GetStr(string name)
|
|
{
|
|
ConsoleParamValue v = this[name];
|
|
if (v == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return v.StrValue;
|
|
}
|
|
|
|
public int GetInt(string name)
|
|
{
|
|
ConsoleParamValue v = this[name];
|
|
if (v == null)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return v.IntValue;
|
|
}
|
|
|
|
public bool GetYes(string name)
|
|
{
|
|
return Str.StrToBool(name);
|
|
}
|
|
}
|
|
|
|
public class ConsoleParamValue : IComparable<ConsoleParamValue>, IEquatable<ConsoleParamValue>
|
|
{
|
|
public readonly string Name;
|
|
public readonly string StrValue;
|
|
public readonly int IntValue;
|
|
public readonly bool BoolValue;
|
|
public readonly bool IsEmpty;
|
|
public readonly bool IsDefaultParam;
|
|
|
|
public ConsoleParamValue(string name, string strValue, int intValue)
|
|
: this(name, strValue, intValue, false)
|
|
{
|
|
}
|
|
public ConsoleParamValue(string name, string strValue, int intValue, bool isDefaultParam)
|
|
{
|
|
this.Name = name;
|
|
this.IntValue = intValue;
|
|
this.StrValue = strValue;
|
|
this.BoolValue = Str.StrToBool(strValue);
|
|
this.IsDefaultParam = isDefaultParam;
|
|
|
|
this.IsEmpty = Str.IsEmptyStr(strValue);
|
|
}
|
|
|
|
public int CompareTo(ConsoleParamValue other)
|
|
{
|
|
return Str.StrCmpiRetInt(this.Name, other.Name);
|
|
}
|
|
|
|
public bool Equals(ConsoleParamValue other)
|
|
{
|
|
return Str.StrCmpi(this.Name, other.Name);
|
|
}
|
|
}
|
|
|
|
public class ConsoleCommandParam : Attribute
|
|
{
|
|
}
|
|
|
|
public class ConsoleCommandMethod : Attribute
|
|
{
|
|
public readonly string Description;
|
|
public readonly string ArgsHelp;
|
|
public readonly string BodyHelp;
|
|
public readonly SortedList<string, string> ParamHelp;
|
|
|
|
internal BindingFlags bindingFlag;
|
|
internal MemberInfo memberInfo;
|
|
internal MethodInfo methodInfo;
|
|
internal string name;
|
|
|
|
public ConsoleCommandMethod(string description, string argsHelp, string bodyHelp, params string[] paramHelp)
|
|
{
|
|
this.Description = description;
|
|
this.ArgsHelp = argsHelp;
|
|
this.BodyHelp = bodyHelp;
|
|
this.ParamHelp = new SortedList<string, string>(new StrComparer(false));
|
|
|
|
foreach (string s in paramHelp)
|
|
{
|
|
int i = s.IndexOf(":");
|
|
if (i == -1)
|
|
{
|
|
throw new ArgumentException(s);
|
|
}
|
|
|
|
this.ParamHelp.Add(s.Substring(0, i), s.Substring(i + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class ConsoleErrorCode
|
|
{
|
|
public const int ERR_BAD_COMMAND_OR_PARAM = -100001;
|
|
public const int ERR_INNER_EXCEPTION = -100002;
|
|
public const int ERR_USER_CANCELED = -100003;
|
|
|
|
public static string ErrorCodeToString(int code)
|
|
{
|
|
bool b;
|
|
|
|
return ErrorCodeToString(code, out b);
|
|
}
|
|
public static string ErrorCodeToString(int code, out bool unknownError)
|
|
{
|
|
unknownError = false;
|
|
|
|
switch (code)
|
|
{
|
|
case ERR_BAD_COMMAND_OR_PARAM:
|
|
return "Bad command or parameters.";
|
|
|
|
case ERR_USER_CANCELED:
|
|
return "User canceled.";
|
|
|
|
case ERR_INNER_EXCEPTION:
|
|
default:
|
|
unknownError = true;
|
|
return string.Format("Unknown Error {0}", code);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ConsoleService
|
|
{
|
|
IO inFile;
|
|
Buf inBuf;
|
|
IO outFile;
|
|
int win32_OldConsoleWidth;
|
|
|
|
public const int MaxPromptStrSize = 65536;
|
|
public const int Win32DefaultConsoleWidth = 100;
|
|
|
|
ConsoleType consoleType;
|
|
public ConsoleType ConsoleType
|
|
{
|
|
get { return consoleType; }
|
|
}
|
|
|
|
int retCode;
|
|
public int RetCode
|
|
{
|
|
get { return retCode; }
|
|
}
|
|
|
|
string retErrorMessage;
|
|
public string RetErrorMessage
|
|
{
|
|
get
|
|
{
|
|
bool b;
|
|
string s = ConsoleErrorCode.ErrorCodeToString(this.RetCode, out b);
|
|
|
|
if (b)
|
|
{
|
|
s = this.retErrorMessage;
|
|
}
|
|
|
|
Str.NormalizeString(ref s);
|
|
|
|
return s;
|
|
}
|
|
}
|
|
|
|
ConsoleFreeDelegate free;
|
|
|
|
ConsoleReadLineDelegate readLine;
|
|
|
|
ConsoleReadPasswordDelegate readPassword;
|
|
|
|
ConsoleWriteDelegate write;
|
|
|
|
ConsoleGetWidthDelegate getWidth;
|
|
|
|
SortedList<string, ConsoleCommandMethod> currentCmdList = null;
|
|
|
|
|
|
private ConsoleService()
|
|
{
|
|
}
|
|
|
|
public static int EntryPoint(string cmdLine, string programName, Type commandClass)
|
|
{
|
|
string s;
|
|
return EntryPoint(cmdLine, programName, commandClass, out s);
|
|
}
|
|
public static int EntryPoint(string cmdLine, string programName, Type commandClass, out string lastErrorMessage)
|
|
{
|
|
int ret = 0;
|
|
string infile, outfile;
|
|
string csvmode;
|
|
ConsoleService c;
|
|
|
|
lastErrorMessage = "";
|
|
|
|
infile = ParseCommand(cmdLine, "in");
|
|
outfile = ParseCommand(cmdLine, "out");
|
|
if (Str.IsEmptyStr(infile))
|
|
{
|
|
infile = null;
|
|
}
|
|
if (Str.IsEmptyStr(outfile))
|
|
{
|
|
outfile = null;
|
|
}
|
|
c = ConsoleService.NewLocalConsoleService(infile, outfile);
|
|
|
|
csvmode = ParseCommand(cmdLine, "csv");
|
|
if (csvmode != null)
|
|
{
|
|
c.consoleType = ConsoleType.Csv;
|
|
}
|
|
|
|
if (c.DispatchCommand(cmdLine, ">", commandClass) == false)
|
|
{
|
|
ret = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
|
|
}
|
|
else
|
|
{
|
|
ret = c.retCode;
|
|
}
|
|
|
|
lastErrorMessage = c.RetErrorMessage;
|
|
|
|
return ret;
|
|
}
|
|
|
|
public bool WriteLine(object value)
|
|
{
|
|
return WriteLine(value.ToString());
|
|
}
|
|
public bool WriteLine(string str)
|
|
{
|
|
return localWrite(str);
|
|
}
|
|
public bool WriteLine(string format, object arg0)
|
|
{
|
|
return WriteLine(string.Format(format, arg0));
|
|
}
|
|
public bool WriteLine(string format, params object[] arg)
|
|
{
|
|
return WriteLine(string.Format(format, arg));
|
|
}
|
|
|
|
public string ReadLine(string prompt)
|
|
{
|
|
return ReadLine(prompt, false);
|
|
}
|
|
public string ReadLine(string prompt, bool noFile)
|
|
{
|
|
return localReadLine(prompt, noFile);
|
|
}
|
|
|
|
public string ReadPassword(string prompt)
|
|
{
|
|
return localReadPassword(prompt);
|
|
}
|
|
|
|
public static ConsolePromptProcDelegate Prompt
|
|
{
|
|
get { return new ConsolePromptProcDelegate(prompt); }
|
|
}
|
|
static string prompt(ConsoleService c, object param)
|
|
{
|
|
string p = (param == null) ? Resources.CMD_PROMPT : (string)param;
|
|
|
|
return c.readLine(p, true);
|
|
}
|
|
|
|
public static ConsoleEvalProcDelegate EvalIsFile
|
|
{
|
|
get { return new ConsoleEvalProcDelegate(evalIsFile); }
|
|
}
|
|
static bool evalIsFile(ConsoleService c, string str, object param)
|
|
{
|
|
string tmp;
|
|
if (c == null || str == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
tmp = str;
|
|
|
|
if (Str.IsEmptyStr(tmp))
|
|
{
|
|
c.write(Resources.CMD_FILE_NAME_EMPTY);
|
|
return false;
|
|
}
|
|
|
|
if (IO.IsFileExists(tmp) == false)
|
|
{
|
|
c.write(Str.FormatC(Resources.CMD_FILE_NOT_FOUND, tmp));
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static ConsoleEvalProcDelegate EvalInt1
|
|
{
|
|
get { return new ConsoleEvalProcDelegate(evalInt1); }
|
|
}
|
|
static bool evalInt1(ConsoleService c, string str, object param)
|
|
{
|
|
string p = (param == null) ? Resources.CMD_EVAL_INT : (string)param;
|
|
|
|
if (Str.StrToInt(str) == 0)
|
|
{
|
|
c.write(p);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static ConsoleEvalProcDelegate EvalNotEmpty
|
|
{
|
|
get { return new ConsoleEvalProcDelegate(evalNotEmpty); }
|
|
}
|
|
static bool evalNotEmpty(ConsoleService c, string str, object param)
|
|
{
|
|
string p = (param == null) ? Resources.CMD_EVAL_NOT_EMPTY : (string)param;
|
|
|
|
if (Str.IsEmptyStr(str) == false)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
c.write(p);
|
|
|
|
return false;
|
|
}
|
|
|
|
public static ConsoleEvalProcDelegate EvalMinMax
|
|
{
|
|
get { return new ConsoleEvalProcDelegate(evalMinMax); }
|
|
}
|
|
static bool evalMinMax(ConsoleService c, string str, object param)
|
|
{
|
|
string tag;
|
|
int v;
|
|
if (param == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ConsoleEvalMinMaxParam e = (ConsoleEvalMinMaxParam)param;
|
|
|
|
if (Str.IsEmptyStr(e.ErrorMessageString))
|
|
{
|
|
tag = Resources.CMD_EVAL_MIN_MAX;
|
|
}
|
|
else
|
|
{
|
|
tag = e.ErrorMessageString;
|
|
}
|
|
|
|
v = Str.StrToInt(str);
|
|
|
|
if (v >= e.MinValue && v <= e.MaxValue)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
c.write(Str.FormatC(tag, e.MinValue, e.MaxValue));
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void PrintCmdHelp(string cmdName, List<string> paramList)
|
|
{
|
|
string tmp;
|
|
string buf;
|
|
string description, args, help;
|
|
List<string> t;
|
|
int width;
|
|
int i;
|
|
string space;
|
|
if (cmdName == null || paramList == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
width = GetConsoleWidth() - 2;
|
|
|
|
description = this.currentCmdList[cmdName].Description;
|
|
args = this.currentCmdList[cmdName].ArgsHelp;
|
|
help = this.currentCmdList[cmdName].BodyHelp;
|
|
|
|
space = Str.MakeCharArray(' ', 2);
|
|
|
|
tmp = Str.FormatC(Resources.CMD_HELP_TITLE, cmdName);
|
|
this.write(tmp);
|
|
this.write("");
|
|
|
|
this.write(Resources.CMD_HELP_DESCRIPTION);
|
|
t = Str.StrArrayToList(SeparateStringByWidth(description, width - 2));
|
|
for (i = 0; i < t.Count; i++)
|
|
{
|
|
buf = Str.FormatC("%S%s", space, t[i]);
|
|
this.write(buf);
|
|
}
|
|
this.write("");
|
|
|
|
this.write(Resources.CMD_HELP_HELP);
|
|
t = Str.StrArrayToList(SeparateStringByWidth(help, width - 2));
|
|
for (i = 0; i < t.Count; i++)
|
|
{
|
|
buf = Str.FormatC("%S%s", space, t[i]);
|
|
this.write(buf);
|
|
}
|
|
this.write("");
|
|
|
|
this.write(Resources.CMD_HELP_USAGE);
|
|
t = Str.StrArrayToList(SeparateStringByWidth(args, width - 2));
|
|
for (i = 0; i < t.Count; i++)
|
|
{
|
|
buf = Str.FormatC("%S%s", space, t[i]);
|
|
this.write(buf);
|
|
}
|
|
|
|
if (paramList.Count >= 1)
|
|
{
|
|
this.write("");
|
|
this.write(Resources.CMD_HELP_ARGS);
|
|
PrintCandidateHelp(cmdName, paramList.ToArray(), 2, this.currentCmdList);
|
|
}
|
|
}
|
|
|
|
public void PrintCandidateHelp(string cmdName, string[] candidateList, int leftSpace, SortedList<string, ConsoleCommandMethod> ccList)
|
|
{
|
|
int console_width;
|
|
int max_keyword_width;
|
|
List<string> o;
|
|
int i;
|
|
string tmpbuf;
|
|
string left_space_array;
|
|
string max_space_array;
|
|
if (candidateList == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
console_width = GetConsoleWidth() - 1;
|
|
|
|
left_space_array = Str.MakeCharArray(' ', leftSpace);
|
|
|
|
o = new List<string>();
|
|
|
|
max_keyword_width = 0;
|
|
|
|
for (i = 0; i < candidateList.Length; i++)
|
|
{
|
|
int keyword_width;
|
|
|
|
o.Add(candidateList[i]);
|
|
|
|
keyword_width = Str.GetStrWidth(candidateList[i]);
|
|
if (cmdName != null)
|
|
{
|
|
if (candidateList[i].StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false)
|
|
{
|
|
keyword_width += 1;
|
|
}
|
|
else
|
|
{
|
|
keyword_width -= 2;
|
|
}
|
|
}
|
|
|
|
max_keyword_width = Math.Max(max_keyword_width, keyword_width);
|
|
}
|
|
|
|
max_space_array = Str.MakeCharArray(' ', max_keyword_width);
|
|
|
|
for (i = 0; i < o.Count; i++)
|
|
{
|
|
string tmp;
|
|
string name = o[i];
|
|
List<string> t;
|
|
string help;
|
|
int j;
|
|
int keyword_start_width = leftSpace;
|
|
int descript_start_width = leftSpace + max_keyword_width + 1;
|
|
int descript_width;
|
|
string space;
|
|
|
|
if (console_width >= (descript_start_width + 5))
|
|
{
|
|
descript_width = console_width - descript_start_width - 3;
|
|
}
|
|
else
|
|
{
|
|
descript_width = 2;
|
|
}
|
|
|
|
if (cmdName != null && name.StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false)
|
|
{
|
|
tmp = Str.FormatC("/%s", name);
|
|
}
|
|
else
|
|
{
|
|
if (cmdName == null)
|
|
{
|
|
tmp = name;
|
|
}
|
|
else
|
|
{
|
|
if (name.Length >= 1)
|
|
{
|
|
tmp = name.Substring(1);
|
|
}
|
|
else
|
|
{
|
|
tmp = "";
|
|
}
|
|
|
|
if (tmp.Length >= 1)
|
|
{
|
|
tmp = tmp.Substring(0, tmp.Length - 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cmdName == null)
|
|
{
|
|
help = ccList[name].Description;
|
|
}
|
|
else
|
|
{
|
|
if (ccList[cmdName].ParamHelp.ContainsKey(name))
|
|
{
|
|
help = ccList[cmdName].ParamHelp[name];
|
|
}
|
|
else
|
|
{
|
|
help = Resources.CMD_UNKNOWN_PARAM;
|
|
}
|
|
}
|
|
|
|
space = Str.MakeCharArray(' ', max_keyword_width - Str.GetStrWidth(name) -
|
|
(cmdName == null ? 0 : (name.StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false ? 1 : -2)));
|
|
|
|
t = Str.StrArrayToList(SeparateStringByWidth(help, descript_width));
|
|
|
|
for (j = 0; j < t.Count; j++)
|
|
{
|
|
if (j == 0)
|
|
{
|
|
tmpbuf = Str.FormatC("%S%S%S - %s",
|
|
left_space_array, tmp, space, t[j]);
|
|
}
|
|
else
|
|
{
|
|
tmpbuf = Str.FormatC("%S%S %s",
|
|
left_space_array, max_space_array, t[j]);
|
|
}
|
|
|
|
this.write(tmpbuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string[] SeparateStringByWidth(string str, int width)
|
|
{
|
|
if (str == null)
|
|
{
|
|
return new string[0];
|
|
}
|
|
if (width <= 0)
|
|
{
|
|
width = 1;
|
|
}
|
|
|
|
StringBuilder tmp = new StringBuilder();
|
|
int len, i;
|
|
List<string> o = new List<string>();
|
|
|
|
str += (char)0;
|
|
len = str.Length;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
char c = str[i];
|
|
|
|
switch (c)
|
|
{
|
|
case (char)0:
|
|
case '\r':
|
|
case '\n':
|
|
if (c == '\r')
|
|
{
|
|
if (str[i + 1] == '\n')
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
|
|
o.Add(tmp.ToString());
|
|
tmp = new StringBuilder();
|
|
break;
|
|
|
|
default:
|
|
tmp.Append(c);
|
|
if (Str.GetStrWidth(tmp.ToString()) >= width)
|
|
{
|
|
o.Add(tmp.ToString());
|
|
tmp = new StringBuilder();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (o.Count == 0)
|
|
{
|
|
o.Add("");
|
|
}
|
|
|
|
return o.ToArray();
|
|
}
|
|
|
|
public static bool IsHelpStr(string str)
|
|
{
|
|
if (str == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (Str.IsStrInList(str, true,
|
|
"help", "?", "man", "/man", "-man", "--man",
|
|
"/help", "/?", "-help", "-?",
|
|
"/h", "--help", "--?"))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool DispatchCommand(string execCommandOrNull, string prompt, Type commandClass)
|
|
{
|
|
return DispatchCommand(execCommandOrNull, prompt, commandClass, null);
|
|
}
|
|
public bool DispatchCommand(string execCommandOrNull, string prompt, Type commandClass, object invokerInstance)
|
|
{
|
|
SortedList<string, ConsoleCommandMethod> cmdList = GetCommandList(commandClass);
|
|
|
|
currentCmdList = cmdList;
|
|
try
|
|
{
|
|
string str, tmp, cmd_name;
|
|
bool b_exit = false;
|
|
string cmd_param;
|
|
int ret = 0;
|
|
List<string> t, candidate;
|
|
int i;
|
|
|
|
if (Str.IsEmptyStr(execCommandOrNull))
|
|
{
|
|
RETRY:
|
|
tmp = prompt;
|
|
str = this.readLine(tmp, false);
|
|
|
|
if (str != null && Str.IsEmptyStr(str))
|
|
{
|
|
goto RETRY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (prompt != null)
|
|
{
|
|
if (this.consoleType != ConsoleType.Csv)
|
|
{
|
|
}
|
|
}
|
|
str = execCommandOrNull;
|
|
}
|
|
|
|
if (str == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
str = Str.TrimCrlf(str).Trim();
|
|
|
|
if (Str.IsEmptyStr(str))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (SeparateCommandAndParam(str, out cmd_name, out cmd_param) == false)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (cmd_name.Length >= 2 && cmd_name[0] == '?' && cmd_name[1] != '?')
|
|
{
|
|
cmd_name = cmd_name.Substring(1);
|
|
cmd_param = "/?";
|
|
}
|
|
|
|
if (cmd_name.Length >= 2 && cmd_name.EndsWith("?") && cmd_name[cmd_name.Length - 2] != '?')
|
|
{
|
|
cmd_name = cmd_name.Substring(0, cmd_name.Length - 1);
|
|
cmd_param = "/?";
|
|
}
|
|
|
|
t = new List<string>();
|
|
for (i = 0; i < cmdList.Count; i++)
|
|
{
|
|
t.Add(cmdList.Keys[i]);
|
|
}
|
|
|
|
if (IsHelpStr(cmd_name))
|
|
{
|
|
if (Str.IsEmptyStr(cmd_param))
|
|
{
|
|
this.write(Str.FormatC(Resources.CMD_HELP_1, t.Count));
|
|
|
|
string[] candidateList = t.ToArray();
|
|
|
|
PrintCandidateHelp(null, candidateList, 1, cmdList);
|
|
|
|
this.write("");
|
|
this.write(Resources.CMD_HELP_2);
|
|
}
|
|
else
|
|
{
|
|
string tmp2, tmp3;
|
|
if (SeparateCommandAndParam(cmd_param, out tmp2, out tmp3))
|
|
{
|
|
bool b = true;
|
|
|
|
if (IsHelpStr(tmp2))
|
|
{
|
|
b = false;
|
|
}
|
|
|
|
if (b)
|
|
{
|
|
DispatchCommand(Str.FormatC("%S /help", tmp2), null, commandClass, invokerInstance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (Str.StrCmpi(cmd_name, "exit") ||
|
|
Str.StrCmpi(cmd_name, "quit"))
|
|
{
|
|
b_exit = true;
|
|
}
|
|
else
|
|
{
|
|
candidate = Str.StrArrayToList(GetRealnameCandidate(cmd_name, t.ToArray()));
|
|
|
|
if (candidate == null || candidate.Count == 0)
|
|
{
|
|
this.write(Str.FormatC(Resources.CON_UNKNOWN_CMD, cmd_name));
|
|
|
|
this.retCode = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
|
|
}
|
|
else if (candidate.Count >= 2)
|
|
{
|
|
this.write(Str.FormatC(Resources.CON_AMBIGIOUS_CMD, cmd_name));
|
|
this.write(Resources.CON_AMBIGIOUS_CMD_1);
|
|
string[] candidateArray = candidate.ToArray();
|
|
|
|
PrintCandidateHelp(null, candidateArray, 1, cmdList);
|
|
this.write(Resources.CON_AMBIGIOUS_CMD_2);
|
|
|
|
this.retCode = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
|
|
}
|
|
else
|
|
{
|
|
string real_cmd_name;
|
|
int j;
|
|
|
|
real_cmd_name = candidate[0];
|
|
|
|
for (j = 0; j < cmdList.Count; j++)
|
|
{
|
|
if (Str.Equals(cmdList.Values[j].name, real_cmd_name))
|
|
{
|
|
if (this.consoleType != ConsoleType.Csv)
|
|
{
|
|
this.write(Str.FormatC(Resources.CMD_EXEC_MSG_NAME,
|
|
cmdList.Values[j].name,
|
|
cmdList.Values[j].Description));
|
|
}
|
|
|
|
object srcObject = null;
|
|
if (cmdList.Values[j].methodInfo.IsStatic == false)
|
|
{
|
|
srcObject = invokerInstance;
|
|
}
|
|
object[] paramList =
|
|
{
|
|
this,
|
|
real_cmd_name,
|
|
cmd_param,
|
|
};
|
|
|
|
try
|
|
{
|
|
ret = (int)cmdList.Values[j].methodInfo.Invoke(srcObject, paramList);
|
|
}
|
|
catch (TargetInvocationException ex)
|
|
{
|
|
Exception ex2 = ex.GetBaseException();
|
|
|
|
if (ex2 is ConsoleUserCancelException)
|
|
{
|
|
this.write(Resources.CON_USER_CANCELED);
|
|
this.write("");
|
|
this.retCode = ConsoleErrorCode.ERR_USER_CANCELED;
|
|
}
|
|
else
|
|
{
|
|
this.write(ex2.ToString());
|
|
this.write("");
|
|
|
|
this.retCode = ConsoleErrorCode.ERR_INNER_EXCEPTION;
|
|
this.retErrorMessage = ex2.Message;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if (ret == -1)
|
|
{
|
|
b_exit = true;
|
|
}
|
|
else
|
|
{
|
|
this.retCode = ret;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (b_exit)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
finally
|
|
{
|
|
currentCmdList = null;
|
|
}
|
|
}
|
|
|
|
public static SortedList<string, ConsoleCommandMethod> GetCommandList(Type commandClass)
|
|
{
|
|
SortedList<string, ConsoleCommandMethod> cmdList = new SortedList<string, ConsoleCommandMethod>(new StrComparer(false));
|
|
|
|
BindingFlags[] searchFlags =
|
|
{
|
|
BindingFlags.Static | BindingFlags.NonPublic,
|
|
BindingFlags.Static | BindingFlags.Public,
|
|
BindingFlags.Instance | BindingFlags.NonPublic,
|
|
BindingFlags.Instance | BindingFlags.Public,
|
|
};
|
|
|
|
foreach (BindingFlags bFlag in searchFlags)
|
|
{
|
|
MemberInfo[] members = commandClass.GetMembers(bFlag);
|
|
|
|
foreach (MemberInfo info in members)
|
|
{
|
|
if ((info.MemberType & MemberTypes.Method) != 0)
|
|
{
|
|
MethodInfo mInfo = commandClass.GetMethod(info.Name, bFlag);
|
|
|
|
object[] customAtts = mInfo.GetCustomAttributes(true);
|
|
|
|
foreach (object att in customAtts)
|
|
{
|
|
if (att is ConsoleCommandMethod)
|
|
{
|
|
ConsoleCommandMethod cc = (ConsoleCommandMethod)att;
|
|
cc.bindingFlag = bFlag;
|
|
cc.memberInfo = info;
|
|
cc.methodInfo = mInfo;
|
|
cc.name = info.Name;
|
|
|
|
cmdList.Add(info.Name, cc);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return cmdList;
|
|
}
|
|
|
|
public int GetConsoleWidth()
|
|
{
|
|
int size = this.getWidth();
|
|
|
|
if (size == 0)
|
|
{
|
|
size = 80;
|
|
}
|
|
|
|
if (size < 32)
|
|
{
|
|
size = 32;
|
|
}
|
|
|
|
if (size > 65535)
|
|
{
|
|
size = 65535;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
public static bool SeparateCommandAndParam(string src, out string cmd, out string param)
|
|
{
|
|
int i, len;
|
|
StringBuilder tmp;
|
|
string src_tmp;
|
|
cmd = param = null;
|
|
if (src == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
src_tmp = Str.TrimCrlf(src).Trim();
|
|
|
|
len = src_tmp.Length;
|
|
tmp = new StringBuilder();
|
|
|
|
for (i = 0; i < (len + 1); i++)
|
|
{
|
|
char c;
|
|
|
|
if (i != len)
|
|
{
|
|
c = src_tmp[i];
|
|
}
|
|
else
|
|
{
|
|
c = (char)0;
|
|
}
|
|
|
|
switch (c)
|
|
{
|
|
case (char)0:
|
|
case ' ':
|
|
case '\t':
|
|
if (Str.IsEmptyStr(tmp.ToString()))
|
|
{
|
|
return false;
|
|
}
|
|
cmd = tmp.ToString().Trim();
|
|
goto ESCAPE;
|
|
|
|
default:
|
|
tmp.Append(c);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ESCAPE:
|
|
param = src_tmp.Substring(tmp.Length).Trim();
|
|
|
|
return true;
|
|
}
|
|
|
|
public static string[] GetRealnameCandidate(string inputName, string[] realNameList)
|
|
{
|
|
List<string> o = new List<string>();
|
|
if (inputName == null || realNameList == null)
|
|
{
|
|
return new string[0];
|
|
}
|
|
|
|
int i;
|
|
bool ok = false;
|
|
for (i = 0; i < realNameList.Length; i++)
|
|
{
|
|
string name = realNameList[i];
|
|
|
|
if (Str.StrCmpi(name, inputName))
|
|
{
|
|
o.Add(name);
|
|
ok = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ok == false)
|
|
{
|
|
for (i = 0; i < realNameList.Length; i++)
|
|
{
|
|
string name = realNameList[i];
|
|
|
|
if (IsOmissionName(inputName, name) ||
|
|
IsNameInRealName(inputName, name))
|
|
{
|
|
o.Add(name);
|
|
ok = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
return o.ToArray();
|
|
}
|
|
else
|
|
{
|
|
return new string[0];
|
|
}
|
|
}
|
|
|
|
public static bool IsOmissionName(string inputName, string realName)
|
|
{
|
|
string oname;
|
|
if (inputName == null || realName == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (Str.IsAllUpperStr(realName))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
oname = GetOmissionName(realName);
|
|
|
|
if (Str.IsEmptyStr(oname))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (oname.StartsWith(inputName, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (inputName.StartsWith(oname, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
if (realName.EndsWith(inputName.Substring(oname.Length), StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static string GetOmissionName(string src)
|
|
{
|
|
int i, len;
|
|
if (src == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
string dst = "";
|
|
len = src.Length;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
char c = src[i];
|
|
|
|
if ((c >= '0' && c <= '9') ||
|
|
(c >= 'A' && c <= 'Z'))
|
|
{
|
|
dst += c;
|
|
}
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
public static bool IsNameInRealName(string inputName, string realName)
|
|
{
|
|
if (inputName == null || realName == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (realName.StartsWith(inputName, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public ConsoleParamValueList ParseCommandList(string cmdName, string command, ConsoleParam[] param)
|
|
{
|
|
ConsoleParamValueList ret = parseCommandLineMain(cmdName, command, param);
|
|
|
|
if (ret == null)
|
|
{
|
|
throw new ConsoleUserCancelException("");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
private ConsoleParamValueList parseCommandLineMain(string cmdName, string command, ConsoleParam[] param)
|
|
{
|
|
int i;
|
|
ConsoleParamValueList o;
|
|
List<string> param_list;
|
|
List<string> real_name_list;
|
|
bool help_mode = false;
|
|
string tmp;
|
|
bool ok = true;
|
|
if (command == null || cmdName == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
for (i = 0; i < param.Length; i++)
|
|
{
|
|
if (Str.IsEmptyStr(param[i].Name) == false)
|
|
{
|
|
if (param[i].Name.StartsWith("["))
|
|
{
|
|
param[i].Tmp = "";
|
|
}
|
|
else
|
|
{
|
|
param[i].Tmp = null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
param[i].Tmp = "";
|
|
}
|
|
}
|
|
|
|
param_list = Str.StrArrayToList(GetCommandNameList(command));
|
|
|
|
real_name_list = new List<string>();
|
|
|
|
for (i = 0; i < param.Length; i++)
|
|
{
|
|
real_name_list.Add(param[i].Name);
|
|
}
|
|
|
|
for (i = 0; i < param_list.Count; i++)
|
|
{
|
|
string s = param_list[i];
|
|
|
|
if (Str.StrCmpi(s, "help") ||
|
|
Str.StrCmpi(s, "?"))
|
|
{
|
|
help_mode = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
tmp = ParseCommand(command, "");
|
|
if (tmp != null)
|
|
{
|
|
if (Str.StrCmpi(tmp, "?"))
|
|
{
|
|
help_mode = true;
|
|
}
|
|
}
|
|
|
|
if (help_mode)
|
|
{
|
|
PrintCmdHelp(cmdName, real_name_list);
|
|
return null;
|
|
}
|
|
|
|
for (i = 0; i < param_list.Count; i++)
|
|
{
|
|
string[] candidate = GetRealnameCandidate(param_list[i], real_name_list.ToArray());
|
|
|
|
if (candidate != null && candidate.Length >= 1)
|
|
{
|
|
if (candidate.Length >= 2)
|
|
{
|
|
this.write(Str.FormatC(Resources.CON_AMBIGIOUS_PARAM,
|
|
param_list[i]));
|
|
|
|
this.write(Str.FormatC(Resources.CON_AMBIGIOUS_PARAM_1,
|
|
cmdName));
|
|
|
|
PrintCandidateHelp(cmdName, candidate, 1, this.currentCmdList);
|
|
this.write(Resources.CON_AMBIGIOUS_PARAM_2);
|
|
|
|
ok = false;
|
|
}
|
|
else
|
|
{
|
|
int j;
|
|
string real_name = candidate[0];
|
|
|
|
for (j = 0; j < param.Length; j++)
|
|
{
|
|
if (Str.StrCmpi(param[j].Name, real_name))
|
|
{
|
|
param[j].Tmp = param_list[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.write(Str.FormatC(Resources.CON_INVALID_PARAM,
|
|
param_list[i],
|
|
cmdName,
|
|
cmdName));
|
|
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
if (ok == false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
o = new ConsoleParamValueList();
|
|
|
|
for (i = 0; i < param.Length; i++)
|
|
{
|
|
ConsoleParam p = param[i];
|
|
bool is_default_value = false;
|
|
|
|
if (p.Tmp == "")
|
|
{
|
|
is_default_value = true;
|
|
}
|
|
|
|
if (p.Tmp != null || p.PromptProc != null)
|
|
{
|
|
string name = p.Name;
|
|
string tmp2, str;
|
|
|
|
if (p.Tmp != null)
|
|
{
|
|
tmp2 = p.Tmp;
|
|
}
|
|
else
|
|
{
|
|
tmp2 = p.Name;
|
|
}
|
|
|
|
str = ParseCommand(command, tmp2);
|
|
|
|
if (str != null)
|
|
{
|
|
string unistr;
|
|
bool ret;
|
|
EVAL_VALUE:
|
|
unistr = str;
|
|
|
|
if (p.EvalProc != null)
|
|
{
|
|
ret = p.EvalProc(this, unistr, p.EvalProcParam);
|
|
}
|
|
else
|
|
{
|
|
ret = true;
|
|
}
|
|
|
|
if (ret == false)
|
|
{
|
|
string tmp3;
|
|
if (p.PromptProc == null)
|
|
{
|
|
ok = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
str = null;
|
|
tmp3 = p.PromptProc(this, p.PromptProcParam);
|
|
if (tmp3 == null)
|
|
{
|
|
ok = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
this.write("");
|
|
str = tmp3;
|
|
goto EVAL_VALUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
o.Add(new ConsoleParamValue(p.Name, str, Str.StrToInt(str), is_default_value));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (p.PromptProc != null)
|
|
{
|
|
string tmp4;
|
|
tmp4 = p.PromptProc(this, p.PromptProcParam);
|
|
if (tmp4 == null)
|
|
{
|
|
ok = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
this.write("");
|
|
str = tmp4;
|
|
if (true)
|
|
{
|
|
string unistr;
|
|
bool ret;
|
|
EVAL_VALUE:
|
|
unistr = str;
|
|
|
|
if (p.EvalProc != null)
|
|
{
|
|
ret = p.EvalProc(this, unistr, p.EvalProcParam);
|
|
}
|
|
else
|
|
{
|
|
ret = true;
|
|
}
|
|
|
|
if (ret == false)
|
|
{
|
|
if (p.PromptProc == null)
|
|
{
|
|
ok = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
str = null;
|
|
tmp4 = p.PromptProc(this, p.PromptProcParam);
|
|
if (tmp4 == null)
|
|
{
|
|
ok = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
this.write("");
|
|
str = tmp4;
|
|
goto EVAL_VALUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
o.Add(new ConsoleParamValue(p.Name, str, Str.StrToInt(str), is_default_value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ok)
|
|
{
|
|
return o;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static string[] GetCommandNameList(string str)
|
|
{
|
|
if (str == null)
|
|
{
|
|
return new string[0];
|
|
}
|
|
|
|
string[] pl;
|
|
ParseCommand(str, "dummy_str", out pl);
|
|
|
|
return pl;
|
|
}
|
|
|
|
public static string ParseCommand(string str, string name)
|
|
{
|
|
string[] pl;
|
|
return ParseCommand(str, name, out pl);
|
|
}
|
|
public static string ParseCommand(string str, string name, out string[] paramList)
|
|
{
|
|
int i;
|
|
string tmp, ret = null;
|
|
SortedList<string, int> o;
|
|
paramList = null;
|
|
if (str == null)
|
|
{
|
|
return null;
|
|
}
|
|
if (Str.IsEmptyStr(name))
|
|
{
|
|
name = null;
|
|
}
|
|
|
|
o = new SortedList<string, int>(new StrComparer(false));
|
|
|
|
tmp = str.Trim();
|
|
|
|
i = Str.SearchStr(tmp, "/CMD", 0, false);
|
|
|
|
if (i >= 1 && tmp[i - 1] == '/')
|
|
{
|
|
i = -1;
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "/CMD\t", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '/')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "/CMD:", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '/')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "/CMD=", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '/')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "-CMD ", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '-')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "-CMD\t", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '-')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "-CMD:", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '-')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
if (i == -1)
|
|
{
|
|
i = Str.SearchStr(tmp, "-CMD=", 0, false);
|
|
if (i >= 1 && tmp[i - 1] == '-')
|
|
{
|
|
i = -1;
|
|
}
|
|
}
|
|
|
|
if (i != -1)
|
|
{
|
|
string s = "CMD";
|
|
if (o != null)
|
|
{
|
|
if (o.ContainsKey(s) == false)
|
|
{
|
|
o.Add(s, 0);
|
|
}
|
|
}
|
|
if (Str.StrCmpi(name, "CMD"))
|
|
{
|
|
ret = str.Substring(i + 5).Trim();
|
|
}
|
|
else
|
|
{
|
|
tmp = tmp.Substring(0, i);
|
|
}
|
|
}
|
|
|
|
if (ret == null)
|
|
{
|
|
string[] t = Str.ParseCmdLine(tmp);
|
|
|
|
if (t != null)
|
|
{
|
|
for (i = 0; i < t.Length; i++)
|
|
{
|
|
string token = t[i];
|
|
|
|
if ((token[0] == '-' && token[1] != '-') ||
|
|
(Str.StrCmpi(token, "--help")) ||
|
|
(token[0] == '/' && token[1] != '/'))
|
|
{
|
|
int j;
|
|
if (Str.StrCmpi(token, "--help"))
|
|
{
|
|
token = token.Substring(1);
|
|
}
|
|
|
|
j = Str.SearchStr(token, ":", 0, false);
|
|
if (j == -1)
|
|
{
|
|
j = Str.SearchStr(token, "=", 0, false);
|
|
}
|
|
if (j != -1)
|
|
{
|
|
string tmp2;
|
|
string a;
|
|
|
|
tmp2 = token;
|
|
if (tmp2.Length >= j)
|
|
{
|
|
tmp2 = tmp2.Substring(0, j);
|
|
}
|
|
|
|
a = tmp2.Substring(1);
|
|
if (o != null)
|
|
{
|
|
if (o.ContainsKey(a) == false)
|
|
{
|
|
o.Add(a, 0);
|
|
}
|
|
}
|
|
|
|
if (tmp2.Length >= 1 && Str.StrCmpi(name, tmp2.Substring(1)))
|
|
{
|
|
if (ret == null)
|
|
{
|
|
ret = token.Substring(j + 1);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string a = token.Substring(1);
|
|
|
|
if (o != null)
|
|
{
|
|
if (o.ContainsKey(a) == false)
|
|
{
|
|
o.Add(a, 0);
|
|
}
|
|
|
|
if (Str.StrCmpi(name, token.Substring(1)))
|
|
{
|
|
if (ret == null)
|
|
{
|
|
ret = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (name == null)
|
|
{
|
|
if (ret == null)
|
|
{
|
|
if (token.StartsWith("--"))
|
|
{
|
|
ret = token.Substring(1);
|
|
}
|
|
else if (token.StartsWith("//"))
|
|
{
|
|
ret = token.Substring(1);
|
|
}
|
|
else
|
|
{
|
|
ret = token;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (o != null)
|
|
{
|
|
List<string> t = new List<string>();
|
|
|
|
int j;
|
|
for (j = 0; j < o.Count; j++)
|
|
{
|
|
t.Add(o.Keys[j]);
|
|
}
|
|
|
|
paramList = t.ToArray();
|
|
}
|
|
|
|
if (ret != null)
|
|
{
|
|
if (Str.StrCmpi(ret, "none") || Str.StrCmpi(ret, "null"))
|
|
{
|
|
ret = "";
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public static ConsoleService NewLocalConsoleService()
|
|
{
|
|
return NewLocalConsoleService(null, null);
|
|
}
|
|
public static ConsoleService NewLocalConsoleService(string outFileName)
|
|
{
|
|
return NewLocalConsoleService(null, outFileName);
|
|
}
|
|
public static ConsoleService NewLocalConsoleService(string inFileName, string outFileName)
|
|
{
|
|
IO in_io = null, out_io = null;
|
|
|
|
ConsoleService c = new ConsoleService();
|
|
int old_size = 0;
|
|
|
|
c.consoleType = ConsoleType.Local;
|
|
c.free = new ConsoleFreeDelegate(c.localFree);
|
|
c.readLine = new ConsoleReadLineDelegate(c.localReadLine);
|
|
c.readPassword = new ConsoleReadPasswordDelegate(c.localReadPassword);
|
|
c.write = new ConsoleWriteDelegate(c.localWrite);
|
|
c.getWidth = new ConsoleGetWidthDelegate(c.localGetWidth);
|
|
|
|
if (Str.IsEmptyStr(inFileName) == false)
|
|
{
|
|
try
|
|
{
|
|
in_io = IO.FileOpen(inFileName, false);
|
|
}
|
|
catch
|
|
{
|
|
c.write(Str.FormatC(Resources.CON_INFILE_ERROR, inFileName));
|
|
return null;
|
|
}
|
|
c.write(Str.FormatC(Resources.CON_INFILE_START, inFileName));
|
|
}
|
|
|
|
if (Str.IsEmptyStr(outFileName) == false)
|
|
{
|
|
try
|
|
{
|
|
out_io = IO.FileCreate(outFileName);
|
|
}
|
|
catch
|
|
{
|
|
c.write(Str.FormatC(Resources.CON_OUTFILE_ERROR, outFileName));
|
|
if (in_io != null)
|
|
{
|
|
in_io.Close();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
c.write(Str.FormatC(Resources.CON_OUTFILE_START, outFileName));
|
|
}
|
|
|
|
c.inFile = in_io;
|
|
c.outFile = out_io;
|
|
c.win32_OldConsoleWidth = old_size;
|
|
|
|
if (in_io != null)
|
|
{
|
|
byte[] data = in_io.ReadAll();
|
|
|
|
c.inBuf = new Buf(data);
|
|
}
|
|
|
|
Con.SetConsoleService(c);
|
|
|
|
return c;
|
|
}
|
|
|
|
void localFree()
|
|
{
|
|
if (inFile != null)
|
|
{
|
|
inFile.Close();
|
|
inFile = null;
|
|
}
|
|
|
|
if (outFile != null)
|
|
{
|
|
outFile.Close();
|
|
outFile = null;
|
|
}
|
|
}
|
|
|
|
int localGetWidth()
|
|
{
|
|
int ret = Console.WindowWidth;
|
|
|
|
if (ret <= 0)
|
|
{
|
|
ret = 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
string localReadLine(string prompt, bool noFile)
|
|
{
|
|
string ret;
|
|
if (prompt == null)
|
|
{
|
|
prompt = ">";
|
|
}
|
|
|
|
writeOutFile(prompt, false);
|
|
|
|
if (noFile == false && inBuf != null)
|
|
{
|
|
ret = readNextFromInFile();
|
|
|
|
if (ret != null)
|
|
{
|
|
Console.Write(prompt);
|
|
|
|
Console.WriteLine(ret);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.Write(prompt);
|
|
ret = Console.ReadLine();
|
|
|
|
if (ret != null)
|
|
{
|
|
if (ret.IndexOf((char)0x04) != -1 || ret.IndexOf((char)0x1a) != -1)
|
|
{
|
|
ret = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ret != null)
|
|
{
|
|
writeOutFile(ret, true);
|
|
}
|
|
else
|
|
{
|
|
writeOutFile("[EOF]", true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
string localReadPassword(string prompt)
|
|
{
|
|
if (prompt == null)
|
|
{
|
|
prompt = "Password>";
|
|
}
|
|
|
|
Console.Write(prompt);
|
|
writeOutFile(prompt, false);
|
|
|
|
string tmp = Str.PasswordPrompt();
|
|
if (tmp != null)
|
|
{
|
|
writeOutFile("********", true);
|
|
return tmp;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
bool localWrite(string str)
|
|
{
|
|
Console.Write("{0}{1}",
|
|
str,
|
|
(str.EndsWith("\n") ? "" : "\n"));
|
|
|
|
writeOutFile(str, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
string readNextFromInFile()
|
|
{
|
|
if (inBuf == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
string str = inBuf.ReadNextLineAsString();
|
|
if (str == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
str = str.Trim();
|
|
|
|
if (Str.IsEmptyStr(str) == false)
|
|
{
|
|
return str;
|
|
}
|
|
}
|
|
}
|
|
|
|
void writeOutFile(string str, bool addLastCrlf)
|
|
{
|
|
if (outFile != null)
|
|
{
|
|
string tmp = Str.NormalizeCrlf(str);
|
|
|
|
outFile.Write(Str.Utf8Encoding.GetBytes(str));
|
|
|
|
if (str.EndsWith("\n") == false && addLastCrlf)
|
|
{
|
|
outFile.Write(Str.Utf8Encoding.GetBytes(Env.NewLine));
|
|
}
|
|
|
|
outFile.Flush();
|
|
}
|
|
}
|
|
}
|
|
}
|