// ============================================================================= // xtor // ============================================================================= public CacheData(ZIMapApplication application) : base(application.Parent) { this.application = application; connection = application.Connection; server = application.Server; factory = connection.CommandLayer; progress = connection.ProgressReporting; // At least deliver Info level messages ... MonitorLevel = application.MonitorLevel; if(MonitorLevel > ZIMapConnection.Monitor.Info) MonitorLevel = ZIMapConnection.Monitor.Info; Data = data = new DataRefImp(this); }
/// <summary> /// Connect to the IMap server and optionally login. /// </summary> /// <param name="user"> /// An IMap account name or <c>null</c> for no login. /// </param> /// <param name="password"> /// The password for the given account. /// </param> /// <param name="tlsMode"> /// Controls TLS (tranport layer security). /// </param> /// <returns> /// On success <c>true</c> is returned. /// </returns> /// <remarks>This function calls <see cref="ZIMapConnection.GetConnection(string)"/> /// and uses <see cref="ZIMapCommand.Login"/> for login. /// <para /> /// If this method is called while having an open connection <c>Disconnect</c> /// gets called first. /// </remarks> public bool Connect(string user, string password, ZIMapConnection.TlsModeEnum tlsMode) { // step 1: Open a new connection and get factory ... ZIMapConnection.ProgressUpdate(null, 0); if(connection != null) Disconnect(); connection = ZIMapConnection.GetConnection(ServerName, ServerPort, tlsMode, timeout); if(connection != null) { connection.MonitorLevel = MonitorLevel; progress = connection.ProgressReporting; progress.Update(20); factory = connection.CommandLayer; } if(factory == null) { connection = null; MonitorError("Connect: failed to open connection"); return false; } // defaults for logging ... SetMonitorLevel(monitorLevel, monitorAll); // step 2: login string greeting = connection.ProtocolLayer.ServerGreeting; MonitorInfo("Connect: server greeting: " + greeting); progress.Update(40); ZIMapCommand.Login cmd = new ZIMapCommand.Login(factory); cmd.Queue(user, password); if(!cmd.CheckSuccess()) { MonitorError("Connect: login failed"); return false; } username = user; progress.Update(60); // set 3: get server configuration bool bIMap = true; CheckCapability("IMAP4rev1", false, ref bIMap); CheckCapability("NAMESPACE", bIMap, ref enableNamespaces); CheckCapability("QUOTA", false, ref enableQuota); CheckCapability("ACL", false, ref enableRights); CheckCapability("UIDPLUS", bIMap, ref enableUid); progress.Update(80); // step4: get Namespace info if(enableNamespaces) { if(Server.NamespaceDataPersonal.Valid) MonitorInfo("Connect: NAMESPACE enabled"); else { MonitorInfo("Connect: NAMESPACE disabled (not supported)"); enableNamespaces = false; } factory.HierarchyDelimiter = server.DefaultDelimiter; } progress.Done(); return true; }
// ============================================================================= // Main // ============================================================================= public static void Main(string[] args) { uint confirm = 0; ZIMapConnection.TlsModeEnum tlsmode = ZIMapConnection.TlsModeEnum.Automatic; // --- step 1: parse command line arguments ArgsTool.Option[] opts = ArgsTool.Parse(options, args, out Commands); if(opts == null) Fatal("Invalid command line. Try /help to get usage info."); foreach(ArgsTool.Option o in opts) { if(o.Error == ArgsTool.OptionStatus.Ambiguous) Fatal("Ambiguous option: {0}", o.Name); if(o.Error != ArgsTool.OptionStatus.OK) Fatal("Invalid option: {0}. Try /help to get usage info", o.Name); switch(o.Name) { case "?": case "help": Usage(); return; case "command": GetTableBuilder(0); // init TextTool Execute("help -all " + o.Value); return; case "ascii": Ascii = true; TextTool.UseAscii = true; LineTool.EnableColor = false; break; case "confirm": if (o.Value == "on") confirm = 1; else if(o.Value == "off") confirm = 2; else confirm = 0; break; case "output": if (o.Value == "error") Output = OutLevel.Error; else if(o.Value == "brief") Output = OutLevel.Brief; else if(o.Value == "all") Output = OutLevel.All; else Output = OutLevel.Info; break; case "log": Log = o.Value; if(string.IsNullOrEmpty(Log)) Fatal("No log file specified"); break; case "debug": Debug = 1; if(o.Value != null && !uint.TryParse(o.Value, out Debug)) Fatal("Invalid debug level: {0}", o.Value); break; case "server": Server = o.Value; break; case "protocol": Protocol = o.Value; if(o.SubValues != null) { if(o.SubValues[0] == "tls" ) tlsmode = ZIMapConnection.TlsModeEnum.Required; if(o.SubValues[0] == "notls") tlsmode = ZIMapConnection.TlsModeEnum.Disabled; } break; case "timeout": if(!uint.TryParse(o.Value, out Timeout)) Fatal("Invalid timeout: {0}", o.Value); break; case "account": Account = o.Value; break; case "password": Password = o.Value; break; case "mailbox": MailBoxName = o.Value; break; case "--": EndOption = true; break; } } opts = null; // memory can be freed GetTableBuilder(0); // init TextTool if(Log != null) { try { LineTool.LogWriter = new System.IO.StreamWriter(Log); } catch(Exception ex) { Fatal("Failed to open logfile: " + ex.Message); } } // --- step 2: prompt for missing parameters if(Commands != null && Commands.Length > 0) { if(confirm != 1) LineTool.AutoConfirm = true; if(Output == OutLevel.Undefined) Output = OutLevel.Brief; Batch = true; string missing = null; if (Server == null) missing = "server"; else if(Account == null) missing = "account"; if(missing != null) Fatal("Please add a '-{0}' option to your command line", missing); } else { if(confirm == 2) LineTool.AutoConfirm = true; if(Output == OutLevel.Undefined) Output = OutLevel.All; Batch = false; if(Server == null) { Server = LineTool.Prompt("Server "); if(string.IsNullOrEmpty(Server)) return; } if(Account == null) { Account = LineTool.Prompt("Account "); if(string.IsNullOrEmpty(Account)) return; } } if(Password == null) Password = System.Environment.GetEnvironmentVariable("ZIMAP_PWD"); if(string.IsNullOrEmpty(Password)) { Password = LineTool.Prompt("Password"); if(string.IsNullOrEmpty(Password)) return; } // --- step 3: Connect and configure uint port = ZIMapConnection.GetIMapPort(Protocol); if(port == ZIMapConnection.GetIMapPort()) Protocol = "imap"; if(!Batch) Message(string.Format("Connecting {0}://{1}@{2} ...", Protocol, Account, Server)); ZIMapConnection.Callback = new IMapCallback(); App = new ZIMapApplication(Server, port); if(Timeout != 0) App.Timeout = Timeout; DebugLevel(Debug); if(!App.Connect(Account, Password, tlsmode)) Fatal("Failed to connect"); ProgressReporting = App.Connection.ProgressReporting; Cache = new CacheData(App); if(Output >= OutLevel.Info) Info("Server: " + App.Connection.ProtocolLayer.ServerGreeting); if(!App.Factory.HasCapability("IMAP4rev1")) Error("WARNING: This is not an IMAP4rev1 server!"); // --- step 4: Open mailbox, Execute Commands if(MailBoxName == null || Execute("open -write " + MailBoxName)) { // has commands from command line... if(Batch) { // If the "--" syntax is used ... if(EndOption) { // Arguments that contain spaces must be quoted for(uint urun=0; urun < Commands.Length; urun++) if(Commands[urun].Contains(" ")) ZIMapConverter.QuotedString(out Commands[urun], Commands[urun], true); // build command string and split by "--" into single commands string carg = string.Join(" ", Commands); Commands = carg.Split(new string[] { "-- " }, StringSplitOptions.RemoveEmptyEntries); } // Execute the array of commands until failure ... foreach(string cmd in Commands) if(!Execute(cmd)) break; } // prompt for commands... else { Message("Entering command loop. Type 'help -list' to see the list of commands..."); if(App.Server.IsAdmin && App.EnableNamespaces) { Message("You are logged-in as an administrator - changing default namespace..."); Execute("user *"); } while(true) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); string qual = Cache.Data.Qualifier; if(qual == null) qual = "[no qualifier]"; else { uint nsid = App.Server.FindNamespace(qual, false); if(nsid == ZIMapServer.Personal) qual = "[personal]"; else if(nsid == ZIMapServer.Others) qual = "[other users]"; else if(nsid == ZIMapServer.Shared) qual = "[shared folders]"; else if(nsid == ZIMapServer.Search) qual = "[search results]"; } sb.Append(qual); sb.Append(Ascii ? ':' : '■'); string cmd = Cache.Data.Current.Name; if(string.IsNullOrEmpty(cmd)) sb.Append("[no mailbox]"); else sb.Append(cmd); cmd = LineTool.Prompt(sb.ToString()); if(string.IsNullOrEmpty(cmd)) break; Execute(cmd); } } } // --- step 5: Disconnect and exit App.Disconnect(); if(LineTool.LogWriter != null) LineTool.LogWriter.Close(); return; }