]> mj.ucw.cz Git - checkmail.git/blobdiff - cm.c
Fixed a bug in parsing of headers
[checkmail.git] / cm.c
diff --git a/cm.c b/cm.c
index 257ccec763f221ea0f257e365609454c810e8a06..642c5e54dec089b34d7ff2f26a0513b1e9e209b3 100644 (file)
--- a/cm.c
+++ b/cm.c
@@ -38,6 +38,7 @@ static int allow_osd = 1;
 static int minimum_priority;
 static time_t last_scan_time;
 static char *run_cmd = "mutt -f %s";
+static int simple_tab;
 
 struct options {
   int priority;
@@ -52,6 +53,7 @@ struct options {
   int hotkey;
   int led;
   int osd;
+  int unread_is_new;
 };
 
 struct option_node {
@@ -80,6 +82,7 @@ struct mbox {
   int scanning;
   int seen;
   time_t last_time;
+  time_t display_valid_until;
   int last_size, last_pos;
   int total, new, flagged;
   int last_total, last_new, last_flagged;
@@ -146,6 +149,7 @@ init_options(struct options *o)
   o->hotkey = -1;
   o->led = -1;
   o->osd = -1;
+  o->unread_is_new = -1;
 }
 
 static void
@@ -169,6 +173,7 @@ setup_options(struct mbox *b)
        MERGE(hotkey);
        MERGE(led);
        MERGE(osd);
+       MERGE(unread_is_new);
       }
 }
 
@@ -353,6 +358,27 @@ mb_check(const char *p, int len)
   return 1;
 }
 
+static void
+mb_skip(int len)
+{
+  while (len)
+    {
+      int avail = mb_end - mb_cc;
+      if (!avail)
+       {
+         if (mb_ll_get() < 0)
+           return;
+         len--;
+       }
+      else
+       {
+         int next = (avail < len) ? avail : len;
+         len -= next;
+         mb_cc += next;
+       }
+    }
+}
+
 static void
 scan_mbox(struct mbox *b, struct stat *st)
 {
@@ -453,6 +479,7 @@ scan_mbox(struct mbox *b, struct stat *st)
       while ((c = mb_get()) >= 0 && c != '\n')
        ;
 
+      int content_length = -1;
       int new = 1;
       int flagged = 0;
       sender[0] = 0;
@@ -470,6 +497,8 @@ scan_mbox(struct mbox *b, struct stat *st)
                }
              if (c == '\n')
                {
+                 if (!i)
+                   break;
                  int fold = -1;
                  do
                    {
@@ -491,13 +520,18 @@ scan_mbox(struct mbox *b, struct stat *st)
          if (!buf[0])
            break;
          if (!strncasecmp(buf, "Status:", 7))
-           new = 0;
+           {
+             if (!b->o.unread_is_new || strchr(buf + 7, 'R'))
+               new = 0;
+           }
          else if (!strncasecmp(buf, "X-Status:", 9) && strchr(buf+9, 'F'))
            flagged = 1;
          else if (!strncasecmp(buf, "From:", 5))
            strcpy(sender, buf+5);
          else if (!strncasecmp(buf, "Subject:", 8))
            strcpy(subject, buf+8);
+         else if (!strncasecmp(buf, "Content-Length:", 15))
+           content_length = atoi(buf + 15);
        }
 
       b->total++;
@@ -506,13 +540,16 @@ scan_mbox(struct mbox *b, struct stat *st)
       if (flagged)
        b->flagged++;
       if (debug_mode > 1)
-       debug("new=%d flagged=%d sender=<%s> subject=<%s>\n", new, flagged, sender, subject);
+       debug("new=%d flagged=%d len=%d sender=<%s> subject=<%s>\n", new, flagged, content_length, sender, subject);
       if (new || (flagged && !b->snippet_is_new))
        {
          b->snippet_is_new = new;
          prepare_snippets(b, sender, subject);
        }
 
+      if (content_length >= 0)
+       mb_skip(content_length);
+
       int ct = 1;
       while (from[ct])
        {
@@ -608,6 +645,11 @@ scan(int notify)
          redraw_line(b->index);
          refresh();
        }
+      else if (b->display_valid_until <= last_scan_time)
+       {
+         debug("not changed, but needs redraw\n");
+         redraw_line(b->index);
+       }
       else
        debug("not changed\n");
       b->force_refresh = 0;
@@ -631,6 +673,7 @@ static Atom osd_pty;
 static unsigned osd_care;
 #define OSD_MSG_SIZE 1024
 static char osd_last_msg[OSD_MSG_SIZE];
+static time_t osd_last_time;
 
 static void
 x11_init(void)
@@ -838,7 +881,7 @@ rethink_osd(int notify)
     if (b->o.osd > 0)
       {
        p.total_new += b->new;
-       if (b->new && (!p.mbox || p.mbox->o.priority < b->o.priority))
+       if (b->new && b->last_time > osd_last_time && (!p.mbox || p.mbox->o.priority < b->o.priority))
          p.mbox = b;
       }
 
@@ -856,6 +899,7 @@ rethink_osd(int notify)
        }
       else
        debug("OSD: No changes\n");
+      osd_last_time = time(NULL);
     }
 }
 
@@ -905,6 +949,7 @@ redraw_line(int i)
       int hi = b->o.highlight;
       unsigned namepos = 0;
       unsigned namelen = strlen(b->name);
+      int valid = 3600;
 
       attrset(attrs[cc][hi][M_IDLE]);
       if (b->o.hotkey)
@@ -955,9 +1000,12 @@ redraw_line(int i)
              if (age < 0)
                age = 0;
              if (age < 3600)
-               printw("%2d min  ", age/60);
+               {
+                 printw("%2d min  ", age/60);
+                 valid = 60;
+               }
              else if (age < 86400)
-               printw("%2d hrs  ", age/3600);
+               printw("%2d hr%c  ", age/3600, (age >= 7200 ? 's' : ' '));
              else
                printw("        ");
              snip = 1;
@@ -976,6 +1024,7 @@ redraw_line(int i)
              int xx, yy;
              getyx(stdscr, yy, xx);
              int remains = COLS-1-xx;
+             (void) yy;
 
              char snip[256];
              build_snippet(snip, snip + sizeof(snip) - 1, b);
@@ -993,6 +1042,7 @@ redraw_line(int i)
                }
            }
        }
+      b->display_valid_until = last_scan_time + valid;
     }
   attrset(attrs[0][0][M_IDLE]);
   clrtoeol();
@@ -1199,10 +1249,21 @@ next_active(int since, int step)
   do
     {
       struct mbox *b = mbox_array[i];
-      if (b->new && b->o.priority > bestp)
+      if (simple_tab)
        {
-         besti = i;
-         bestp = b->o.priority;
+         if (b->new)
+           {
+             besti = i;
+             break;
+           }
+       }
+      else
+       {
+         if (b->new && b->o.priority > bestp)
+           {
+             besti = i;
+             bestp = b->o.priority;
+           }
        }
       i = (i+step) % cursor_max;
     }
@@ -1289,6 +1350,7 @@ Options:\n\
 -o <opts>\t\tSet default options for all mailboxes\n\
 -p <pri>\t\tSet minimum priority to show\n\
 -s <key>=<val>\t\tSet on-screen display options (consult OSDD docs)\n\
+-t\t\t\tLet TAB select the next mailbox with new mail, no matter what priority it has\n\
 \n\
 Mailbox options (set with `-o', use upper case to negate):\n\
 0-9\t\t\tSet mailbox priority (0=default)\n\
@@ -1299,6 +1361,7 @@ f\t\t\tShow flagged messages if there are no new ones\n\
 h\t\t\tHide from display\n\
 l<led>\t\t\tLight a keyboard led (1-9) if running on X display\n\
 m\t\t\tShow mailbox name of the sender\n\
+o\t\t\tCount old, but unread messages as new\n\
 p\t\t\tShow personal info (full name) of the sender\n\
 s\t\t\tShow message snippets\n\
 t\t\t\tHighlight the entry\n\
@@ -1359,6 +1422,9 @@ parse_options(char *c)
          case 'm':
            o->sender_mbox = value;
            break;
+         case 'o':
+           o->unread_is_new = value;
+           break;
          case 'p':
            o->sender_personal = value;
            break;
@@ -1384,7 +1450,7 @@ main(int argc, char **argv)
   clist_init(&osd_opts);
 
   int c;
-  while ((c = getopt(argc, argv, "c:dim:o:p:s:")) >= 0)
+  while ((c = getopt(argc, argv, "c:dim:o:p:s:t")) >= 0)
     switch (c)
       {
       case 'c':
@@ -1410,6 +1476,9 @@ main(int argc, char **argv)
       case 's':
        add_osd_opt(optarg);
        break;
+      case 't':
+       simple_tab = 1;
+       break;
       default:
        usage();
       }