Beispiel #1
0
        // =============================================================================
        //        
        // =============================================================================
        public static bool ListMails(CacheData.MailRef headers,
                           bool bTo, bool bFrom, bool bSubject, bool bDate, 
                           bool bSize, bool bFlags, bool bUID, bool bID)
        {
            if(headers.IsNothing) return false;
            ZIMapApplication.MailInfo[] mails = headers.Array(0);
            if(mails.Length < 1)
            {   Message("No mails");
                return true;
            }

            uint ucol = 0;
            if(bTo)      ucol++;
            if(bFrom)    ucol++;
            if(bSubject) ucol++;
            if(bDate)    ucol++;
            if(bSize)    ucol++;
            if(bFlags)   ucol++;
            if(bUID)     ucol++;
            if(bID)      ucol++;

            TextTool.TableBuilder tb = GetTableBuilder(ucol);
            object[] data = new object[ucol];
            ucol = 0;
            if(bID)
            {   data[ucol] = "ID";
                tb.Columns[ucol].RigthAlign = true;
                tb.Columns[ucol++].MaxWidth = 6;
            }
            if(bUID)
            {   data[ucol] = "UID";
                tb.Columns[ucol].RigthAlign = true;
                tb.Columns[ucol++].MaxWidth = 6;
            }
            if(bFrom)
            {   data[ucol] = "From";
                tb.Columns[ucol].RigthAlign = false;
                tb.Columns[ucol++].MaxWidth = 20;
            }
            if(bTo)
            {   data[ucol] = "To";
                tb.Columns[ucol].RigthAlign = false;
                tb.Columns[ucol++].MaxWidth = 20;
            }
            if(bDate)
            {   data[ucol] = "Date";
                tb.Columns[ucol].RigthAlign = true;
                tb.Columns[ucol++].MaxWidth = 20;
            }
            if(bSize)
            {   data[ucol] = "kByte";
                tb.Columns[ucol].RigthAlign = true;
                tb.Columns[ucol++].MaxWidth = 6;
            }
            if(bFlags)
            {   data[ucol] = "Flags";
                tb.Columns[ucol].RigthAlign = false;
                tb.Columns[ucol++].MaxWidth = 32;
            }
            if(bSubject)
            {   data[ucol] = "Subject";
                tb.Columns[ucol].RigthAlign = false;
                tb.Columns[ucol++].MinWidth = 32;
            }
            tb.Header(data);

            ZIMapMessage mail = new ZIMapMessage();
            for(int irun = 0; irun < mails.Length; irun++)
            {   if(!mail.Parse(mails[irun].Literal, false))
                       continue;
                ucol = 0;
                if(bID)      data[ucol++] = mails[irun].Index;
                if(bUID)     data[ucol++] = mails[irun].UID;
                if(bFrom)    data[ucol++] = mail.From;
                if(bTo)      data[ucol++] = mail.To;
                if(bDate)    data[ucol++] = mail.DateISO;
                if(bSize)    data[ucol++] = (mails[irun].Size + 1023) / 1024;
                if(bFlags)   data[ucol++] = string.Join(" ", mails[irun].Flags);
                if(bSubject) data[ucol++] = mail.Subject;
                tb.AddRow(data);
            }
            tb.Footer("");
            tb.PrintTable();
            return true;
        }
Beispiel #2
0
        // =============================================================================
        // Mailbox Export
        // =============================================================================
        /// <summary>
        /// Export mail from a single mailbox.
        /// </summary>
        /// <param name="mbox">
        /// A reference to the mailbox.
        /// </param>
        /// <param name="quoted">
        /// If <c>true</c> export using "From" quoting instead of "Content-Length" headers.
        /// </param>
        /// <param name="uids">
        /// A list of uids to be exported or <c>null</c>
        /// </param>
        /// <param name="mailTotal">
        /// Can specify a total number of mails when multiple mailboxes are going to be
        /// exported.
        /// </param>
        /// <param name="mailCounter">
        /// Incremented for each exported mail.
        /// </param>
        /// <returns>
        /// <c>true</c> on success.
        /// </returns>
        public bool MailboxExport(MBoxRef mbox, bool quoted, 
                                  uint[] uids, uint mailTotal, ref uint mailCounter)
        {
            if(!mbox.IsValid) return false;

            uint ucnt = (uids == null) ? mbox.Messages : (uint)uids.Length;
            if(ucnt > mailTotal) mailTotal = ucnt;
            string mailbox = mbox.Name;

            // get rid of INBOX and prefix personal mailboxes with the account name
            uint rnsi;
            string fullname = server.FriendlyName(mailbox, out rnsi);
            string prefix = server[rnsi].Prefix;
            if(prefix != "" && fullname.StartsWith(prefix))     // strip the ns prefix
                fullname = fullname.Substring(prefix.Length);

            // create the output file
            if (!application.ExportMailbox(fullname, rnsi)) return false;
            if(ucnt == 0) {
                MonitorInfo("Mailbox exported: {0} [no mails]", fullname.PadRight(32));
                return true;
            }

            // open the IMAP mailbox
            if(data.Current.Name != mailbox)
            {   ZIMapCommand.Examine exa = new ZIMapCommand.Examine(factory);
                exa.Queue(mailbox);
                if(!exa.CheckSuccess(":Cannot open Mailbox: " + mailbox))
                    return false;
            }

            // loop over mail items
            ZIMapCommand.Fetch.Item item = new ZIMapCommand.Fetch.Item();
            byte[] head = null;
            byte[] body = null;
            ZIMapCommand.Generic current = null;
            ZIMapFactory.Bulk bulk = factory.CreateBulk("FETCH", 4, uids != null);
            ZIMapMessage msg = new ZIMapMessage();
            uint ucur = 0;                      // current item/UID
            uint uerr = 0;                      // error counter
            uint urun = 0;                      // mail counter
            uint urdy = 0;
            string key = (uids == null) ? "item" : "UID";
            while(urdy < ucnt)
            {   // step 1: queue request and check for response ...
                bool done = bulk.NextCommand(ref current);
                ZIMapCommand.Fetch cmd = (ZIMapCommand.Fetch)current;

                // step 2: check server reply for error ...
                if(done)
                {   ucur = (uids == null) ? ++urdy : uids[urdy++];
                    if (cmd.Items == null || cmd.Items.Length != 1)
                    {   MonitorError(!cmd.CheckSuccess() ?
                            "Cannot fetch mail ({0}={1}): {2}" :
                            "Mail not existing ({0}={1})", key, ucur, cmd.Result.Message);
                        done = false; uerr++;
                    }
                }

                // step 3: process data sent by server ...
                if(done)
                {   item = cmd.Items[0];
                    head = item.Literal(0);
                    body = item.Literal(1);
                    if (head == null)
                    {   MonitorError("Mail data incomplete ({0}={1})", key, ucur);
                        done = false; uerr++;
                    }
                    if(body == null) body = new byte[0];        // message without body
                }
                if(done)
                {   msg.Parse(head, true);

                    // use the server's INTERNALDATE if we got it...
                    DateTime date;
                    string sdat;
                    if (ZIMapFactory.FindInParts(item.Parts, "INTERNALDATE", out sdat))
                        date = ZIMapConverter.DecodeIMapTime(sdat, true);
                    else
                        date = msg.DateBinary;

                    // finally write mail data to file ...
                    string flags = (item.Flags == null) ? null : string.Join(" ", item.Flags);
                    if (!application.Export.WriteMail(msg.From, date, flags, head, body, quoted))
                    {   MonitorError("Mail could not be written ({0}={1})", key, ucur);
                        uerr++;
                    }
                    progress.Update(mailCounter++, mailTotal);
                }

                // step 4: create a new request
                if(urun < ucnt)
                {   ucur = (uids == null) ? ++urun : uids[urun++];
                    cmd.Reset();
                    cmd.Queue(ucur, "FLAGS INTERNALDATE BODY.PEEK[HEADER] BODY.PEEK[TEXT]");
                }
            }
            bulk.Dispose();
            MonitorInfo("Mailbox exported: {0} [{1,4} mails]", fullname.PadRight(32), urun);
            return (uerr == 0);
        }
Beispiel #3
0
        public static bool ShowInfo(object what)
        {
            if(what == null) return false;

            // -----------------------------------------------------------------
            // Server
            // -----------------------------------------------------------------
            if(what is string)
            {
                ListOutput(0, "          ", "Server Information for: " + App.ServerName);
                ListOutput(1, "Security  ", App.Connection.TlsMode.ToString());
                ListOutput(1, "Timeout   ", App.Connection.TransportTimeout.ToString() + " [s]");

                ListOutput(2, "Greeting  ", App.Connection.ProtocolLayer.ServerGreeting);
                ListOutput(1, "Type      ", App.Server.ServerType + " (Subtype: " +
                                            App.Server.ServerSubtype + ")");
                ListOutput(1, "Admin     ", App.Server.IsAdmin ? "yes" : "no");

                ListOutput(2, "Capability", string.Join(" ", App.Factory.Capabilities));
                ListOutput(1, "Rights    ", App.EnableRights ? "enabled" : "disabled");
                string sout = "disabled";
                if(App.EnableQuota)
                    sout = string.Format("enabled (STORAGE={0} MESSAGE={1})",
                                         App.Server.HasLimit("STORAGE") ? "yes" : "no",
                                         App.Server.HasLimit("MESSAGE") ? "yes" : "no");
                ListOutput(1, "Quota     ", sout);

                ListOutput(5, "Namespace ", "Personal=" + App.Server.NamespaceDataPersonal + "\n" +
                                            "Others  =" + App.Server.NamespaceDataOther + "\n" +
                                            "Shared  =" + App.Server.NamespaceDataShared + "\n" +
                                            "Search  =" + App.Server.NamespaceDataSearch);
                return true;
            }

            // -----------------------------------------------------------------
            // Application
            // -----------------------------------------------------------------
            if(what == App)
            {
                ListOutput(0, "          ", "Application Information");
                ListOutput(1, "Runtime   ",
                           System.Environment.Version.ToString() + " (" +
                           System.Environment.OSVersion.ToString() + ")" );
                ListOutput(1, "Version   ",
                           System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
            #if DEBUG
                           + " (DEBUG build)"
            #endif
                           );

                App.Export.Open(null, (char)0, false, false);
                string bfld = ZIMapExport.BaseFolder;
                ListOutput(2, "Path      ", (bfld == "") ? "[not set]" : bfld);

                long mem1 = GC.GetTotalMemory(false) / 1024; Cache.Data.Clear(CacheData.Info.All);
                long mem2 = GC.GetTotalMemory(true)  / 1024;
                ListOutput(5, "Memory    ", string.Format("{0} kByte (minimum is {1} kByte)",
                                                          mem1, mem2));
                return true;

            }

            // -----------------------------------------------------------------
            // Mailbox
            // -----------------------------------------------------------------
            if(what is ZIMapApplication.MailBox)
            {
                ZIMapApplication.MailBox mbox = (ZIMapApplication.MailBox)what;
                ListOutput(0, "          ", "Mailbox Information");
                string msg = mbox.Name;
                if(mbox.Name ==  App.MailboxName)
                    msg = string.Format("{0} (current {1})", msg,
                          App.MailboxIsReadonly ? "Read-Only" : "Writable");
                else
                    msg += " (not current)";
                ListOutput(1, "Mailbox   ", msg);
                ListOutput(1, "Messages  ",
                              string.Format("{0} mails ({1} recent {2} unseen)",
                              mbox.Messages, mbox.Recent, mbox.Unseen));
                ListOutput(1, "Subscribed", mbox.Subscribed ? "yes" : "no");
                ListOutput(2, "Flags     ", string.Join(" ", mbox.Flags));
                ListOutput(1, "Attributes", string.Join(" ", mbox.Attributes));
                string qroot, storage, message;
                FormatQuota(mbox.Name, out storage, out message, out qroot);
                if(qroot == null)
                    ListOutput(5, "Quota     ",      "-none-");
                else
                {   if(message != null) message = "\n" + message;
                    if(storage != null) storage = "\n" + storage;
                    ListOutput(5, "Quota     ",      "Quota Root : " +
                                   qroot + message + storage);
                }
                return true;
            }

            // -----------------------------------------------------------------
            // Mail Item
            // -----------------------------------------------------------------
            if(what is uint[])
            {   uint[] uarg = (uint[])what;
                ZIMapApplication.MailInfo[] mails = Cache.Data.Headers.Array(0);

                uint uuid = uarg[0];
                uint urun;
                for(urun=0; urun < mails.Length; urun++)
                    if(mails[urun].UID == uuid) break;
                if(urun >= mails.Length)
                {   Error("UID not found: " + uuid);
                    return false;
                }
                ZIMapApplication.MailInfo mail = mails[urun];
                ZIMapMessage mesg = new ZIMapMessage();
                if(!mesg.Parse(mail.Literal, false)) return false;

                ZIMapMessage.BodyInfo info = null;
                ZIMapCommand.Fetch cmd = new ZIMapCommand.Fetch(App.Factory);
                cmd.UidCommand = App.EnableUidCommands;
                if((uarg[1] & 2) != 0)
                    cmd.Queue(uuid, "BODY BODY.PEEK[TEXT]");
                else
                    cmd.Queue(uuid, "BODY");
                if(!cmd.CheckSuccess("Failed to get status")) return false;
                if((uarg[1] & 2) != 0)
                {   if(cmd.Result.Literals == null || cmd.Result.Literals.Length < 1)
                    {  Info("Message has no body");
                       return true;
                    }
                    mesg.ParseBody(cmd.Result.Literals[0], 0);
                }
                string[] parts = cmd.Items[0].Parts;
                if(parts != null && parts.Length > 1 && parts[0] == "BODY")
                    info = ZIMapMessage.ParseBodyInfo(parts[1]);

                uint utxt = ListOutput(0, "          ", "Mail Information");

                ListOutput(1, "Item      ", string.Format("{0} (ID={1}  UID={2})",
                                            urun+1, mail.Index, mail.UID));
                ListOutput(1, "From      ", mesg.From);
                ListOutput(1, "To        ", mesg.To);
                ListOutput(1, "Subject   ", mesg.Subject);
                ListOutput(1, "Date      ", mesg.DateISO);
                ListOutput(1, "Size      ", mail.Size.ToString());

                ListOutput(2, "Flags     ", string.Join(" ", mail.Flags));

                if(info != null && info.Parts != null)
                    for(int irun=0; irun < info.Parts.Length; irun++)
                    {   string text = info.Parts[irun].ToString();
                        int icol = text.IndexOf(':');
                        if(icol > 0) text = text.Substring(icol+2);
                        ListOutput((uint)((irun == 0) ? 2 : 1),
                                   ("Part [" + info.Parts[irun].Level + "]").PadRight(10), text);
                     }

                if((uarg[1] & 1) != 0)
                {
                    List<string> llis = new List<string>();
                    //string[] names = item.FieldNames;
                    for(int irun=0; irun < mesg.HeaderCount; irun++)
                    {   string[] lines = TextTool.TextIndent(mesg.FieldKey(irun).PadRight(15) + "  " +
                                                  mesg.FieldText(irun), 17, utxt);
                        llis.AddRange(lines);
                    }
                    if(llis.Count == 0)
                        ListOutput(5, "Headers   ", "-none-");
                    if(llis.Count == 1)
                        ListOutput(5, "Headers   ", llis[0]);
                    else for(int irun=0; irun < llis.Count; irun++)
                    {   if(irun == 0)
                            ListOutput(2, "Headers   ", llis[0]);
                        else
                            ListOutput(1, "          ", llis[irun]);
                    }
                }

                if(mesg.BodyCount > 0)
                {   StringBuilder sb = new StringBuilder();
                    for(int irun=0; irun < mesg.BodyCount; irun++)
                        sb.AppendLine(mesg.BodyLine(irun, null));
                    ListOutput(2, "Body Text ", sb.ToString());
                }
                TextTool.Formatter.WriteLine(
                    TextTool.DecoLine(TextTool.Decoration.Double, 0, utxt+12));
                return true;
            }

            return false;
        }
Beispiel #4
0
        public bool HeadersSort(MailRef headers, string field, bool reverse)
        {
            if(headers.IsNothing) return false;
            uint ulen = headers.Count;
            if(ulen == 0) return true;

            // no sort, do reverse?
            if(string.IsNullOrEmpty(field))
            {   if(reverse) Array.Reverse(headers.Array(0));
                return true;
            }

            // check the field name ...
            ZIMapMessage mail = null;
            switch(field)
            {   case "size":
                case "flags":
                case "id":
                case "uid":     break;                      // no mail parsing
                case "to":
                case "from":
                case "subject":
                case "date":    mail = new ZIMapMessage();  // must parse mail
                                break;
                default:        return false;               // bad field
            }

            // build sort array ...
            object[] keys = new object[ulen];
            for(uint urun=0; urun < ulen; urun++)
            {   // TODO: should use an iterator or Next()
                ZIMapApplication.MailInfo info = headers.Array(0)[urun];
                if(mail != null)
                {   progress.Update(urun, ulen);

                    mail.Parse(info.Literal, true);
                }
                switch(field)
                {   case "size":    keys[urun] = info.Size; break;
                    case "flags":   keys[urun] = string.Join(" ", info.Flags); break;
                    case "id":      keys[urun] = info.Index; break;
                    case "uid":     keys[urun] = info.UID; break;
                    case "to":      keys[urun] = mail.To; break;
                    case "from":    keys[urun] = mail.From; break;
                    case "subject": keys[urun] = mail.Subject; break;
                    case "date":    keys[urun] = mail.DateBinary; break;
                 }
            }

            // TODO: should use a sort method, this code is wrong!
            Array.Sort(keys, headers.Array(0));
            if(reverse) Array.Reverse(headers.Array(0));
            return true;
        }