示例#1
0
            public MailRef(ZIMapApplication.MailInfo[] items, /*bool hasUIDs,*/ string mailbox, uint index)
            {
                // TODO: pseudo names should be: <delimiter>name<delimiter>
                if(mailbox == null) mailbox = ".unnamed.";

                segment = new MailRef.MRefSegment();
                segment.array   = items;
                //segment.hasUIDs = hasUIDs;
                segment.mailbox = mailbox;
                this.index = index;
            }
示例#2
0
 // =============================================================================
 // 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);
 }
示例#3
0
 public void UpdateUsers(ZIMapApplication.MailBox[] users, bool others)
 {
     base.UpdateUsers(new MBoxRef(users), others);
 }
示例#4
0
 public void UpdateHeaders(ZIMapApplication.MailInfo[] headers)
 {
     base.UpdateHeaders(new MailRef(headers, parent.application.MailboxName));
 }
示例#5
0
 public void UpdateFolders(ZIMapApplication.MailBox[] boxes, bool details)
 {
     base.UpdateFolders(new MBoxRef(boxes), details);
 }
示例#6
0
        /// <summary>
        /// Sort mailboxes using namespace information.
        /// </summary>
        /// <param name="mailboxes">
        /// An array of MailBox structures.
        /// </param>
        /// <returns>
        /// A value of <c>true</c> indicates that the array was sorted.
        /// </returns>
        public virtual bool MailboxSort(ZIMapApplication.MailBox[] mailboxes)
        {
            if(mailboxes == null) return false;
            if(mailboxes.Length <= 1) return true;

            string[] keys = new string[mailboxes.Length];

            for(int irun=0; irun < mailboxes.Length; irun++)
            {   string name = mailboxes[irun].Name;
                if(name == null)
                    name = "9";
                else if(name.StartsWith("INBOX"))
                    name = "0" + name;
                else
                {   uint nsi = FindNamespace(name);
                    name = (nsi+1).ToString() + name;
                }
                keys[irun] = name;
            }
            Array.Sort(keys, mailboxes);
            return true;
        }
示例#7
0
        /// <summary>
        /// Make sure that a MailBox array contains only entries from one Namespace.
        /// </summary>
        /// <param name="mailboxes">
        /// An array of MailBox structures.
        /// </param>
        /// <param name="nsIndex">
        /// Used to select the Namespace to which the result should belong.<para/>
        /// <list type="table"><listheader>
        ///    <term>nsIndex Value</term>
        ///    <description>Selected Namespace</description>
        /// </listheader><item>
        ///    <term>Personal (0)</term>
        ///    <description>The current user's namepace (INBOX)</description>
        /// </item><item>
        ///    <term>Others (1)</term>
        ///    <description>Other users</description>
        /// </item><item>
        ///    <term>Shared (2)</term>
        ///    <description>Shared folders</description>
        /// </item><item>
        ///    <term>Search (3)</term>
        ///    <description>Pseudo-Namespace for search results</description>
        /// </item><item>
        ///    <term>Nothing (uint.MaxValue)</term>
        ///    <description>Invalid, returns <c>false</c></description>
        /// </item></list>
        /// </param>
        /// <returns>
        /// A value of <c>true</c> indicates that the array was modified.
        /// </returns>
        public virtual bool MailboxesFilter(ref ZIMapApplication.MailBox[] mailboxes, uint nsIndex)
        {
            if(mailboxes == null || mailboxes.Length < 1) return false;
            if(!namespaceOK || nsIndex > Shared) return false;

            // ok, remove them ...
            int ilas = 0;
            for(int irun=0; irun < mailboxes.Length; irun++)
            {   if(FindNamespace(mailboxes[irun].Name) != nsIndex)
                    continue;
                if(ilas != irun) mailboxes[ilas] = mailboxes[irun];
                ilas++;
            }
            if(ilas == mailboxes.Length) return false;
            Array.Resize(ref mailboxes, ilas);
            return true;
        }
示例#8
0
 public MailRef(ZIMapApplication.MailInfo[] items, string mailbox)
     : this(items, mailbox, 0)
 {
 }
示例#9
0
 /// <summary>Sends a EXAMINE or SELECT if neccessary.</summary>
 /// <returns>On success <c>true</c> is returned.</returns>
 public bool Open(ZIMapApplication application, bool readOnly)
 {
     if(!IsValid) return false;
     if(readOnly || !application.MailboxIsReadonly)  // don't downgrade
         readOnly = application.MailboxIsReadonly;
     bool bok = application.MailboxOpen(Name, readOnly);
     return bok;
 }
示例#10
0
 public bool ExtraSetQuota(ZIMapApplication.QuotaInfo info)
 {
     if(!IsValid) return false;
     UserData data     = Extra;                      // creates instance
     data.QuotaRoot    = info.Valid ? info.QuotaRoot : "";
     data.StorageUsage = info.StorageUsage; data.StorageLimit = info.StorageLimit;
     data.MessageUsage = info.MessageUsage; data.MessageLimit = info.MessageLimit;
     return true;
 }
示例#11
0
 public bool ExtraGetQuota(out ZIMapApplication.QuotaInfo info)
 {
     info = new ZIMapApplication.QuotaInfo();
     if(!HasExtra) return false;
     UserData data = Extra;
     info.QuotaRoot = data.QuotaRoot;
     info.StorageUsage = data.StorageUsage; info.StorageLimit = data.StorageLimit;
     info.MessageUsage = data.MessageUsage; info.MessageLimit = data.MessageLimit;
     return !string.IsNullOrEmpty(data.QuotaRoot);
 }
示例#12
0
 public MBoxRef(ZIMapApplication.MailBox[] boxes, uint index)
 {
     this.index  = index;
     this.length = (boxes == null) ? 0 : (uint)boxes.Length;
     this.boxes  = (length > 0) ? boxes : empty;
 }
示例#13
0
            public bool Append(ZIMapApplication.MailInfo[] items, string mailbox)
            {
                if(items == null) return false;
                uint unew = (uint)items.Length;
                if(unew == 0) return true;

                MRefSegment seg = segment;
                while(seg.next != null) seg = seg.next;     // get last segment
                if(seg.mailbox == mailbox)                  // merge...
                {   uint uold = (uint)seg.array.Length;
                    System.Array.Resize(ref seg.array, (int)(uold+unew));
                    System.Array.Copy(items, 0, seg.array, uold, unew);
                    return true;
                }
                seg.next = new MailRef.MRefSegment();
                seg.next.array   = items;
                //seg.next.hasUIDs = seg.hasUIDs;
                seg.next.mailbox = mailbox;
                return true;
            }
示例#14
0
        // =============================================================================
        // 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;
        }