⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mh.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
    mutt_str_replace (&h->maildir_flags, p);    q = h->maildir_flags;    while (*p)    {      switch (*p)      {      case 'F':	h->flagged = 1;	break;      case 'S':		/* seen */	h->read = 1;	break;      case 'R':		/* replied */	h->replied = 1;	break;      case 'T':		/* trashed */	h->trash = 1;	h->deleted = 1;	break;            default:	*q++ = *p;	break;      }      p++;    }  }    if (q == h->maildir_flags)    FREE (&h->maildir_flags);  else if (q)    *q = '\0';}static void maildir_update_mtime (CONTEXT * ctx){  char buf[_POSIX_PATH_MAX];  struct stat st;  if (ctx->magic == M_MAILDIR)  {    snprintf (buf, sizeof (buf), "%s/%s", ctx->path, "cur");    if (stat (buf, &st) == 0)      ctx->mtime_cur = st.st_mtime;    snprintf (buf, sizeof (buf), "%s/%s", ctx->path, "new");  }  else  {    snprintf (buf, sizeof (buf), "%s/.mh_sequences", ctx->path);    if (stat (buf, &st) == 0)      ctx->mtime_cur = st.st_mtime;    strfcpy (buf, ctx->path, sizeof (buf));  }  if (stat (buf, &st) == 0)    ctx->mtime = st.st_mtime;}/*  * Actually parse a maildir message.  This may also be used to fill * out a fake header structure generated by lazy maildir parsing. */static HEADER *maildir_parse_message (int magic, const char *fname,				      int is_old, HEADER * _h){  FILE *f;  HEADER *h = _h;  struct stat st;  if ((f = fopen (fname, "r")) != NULL)  {    if (!h)      h = mutt_new_header ();    h->env = mutt_read_rfc822_header (f, h, 0, 0);    fstat (fileno (f), &st);    fclose (f);    if (!h->received)      h->received = h->date_sent;    if (h->content->length <= 0)      h->content->length = st.st_size - h->content->offset;    h->index = -1;    if (magic == M_MAILDIR)    {      /*        * maildir stores its flags in the filename, so ignore the       * flags in the header of the message        */      h->old = is_old;      maildir_parse_flags (h, fname);    }    return h;  }  return NULL;}/*  * Note that this routine will _not_ modify the context given by * ctx.  * * It's used in the first parsing pass on maildir and MH folders. * In the MH case, this means full parsing of the folder.  In the * maildir case, it means that we only look at flags, and create a * fake HEADER structure, which may later be filled in by * maildir_parse_message(), when called from * maildir_delayed_parsing(). *  */static int maildir_parse_entry (CONTEXT * ctx, struct maildir ***last,				const char *subdir, const char *fname,				int *count, int is_old, ino_t inode#if USE_HCACHE				, header_cache_t *hc#endif			       ){  struct maildir *entry;  HEADER *h = NULL;  char buf[_POSIX_PATH_MAX];#if USE_HCACHE  void *data;#endif  if (subdir)    snprintf (buf, sizeof (buf), "%s/%s/%s", ctx->path, subdir, fname);  else    snprintf (buf, sizeof (buf), "%s/%s", ctx->path, fname);  if (ctx->magic == M_MH)  {#ifdef USE_HCACHE    if (hc && (data = mutt_hcache_fetch (hc, fname, strlen)))      h = mutt_hcache_restore ((unsigned char *) data, NULL);    else#endif    h = maildir_parse_message (ctx->magic, buf, is_old, NULL);  }  else  {    h = mutt_new_header ();    h->old = is_old;    maildir_parse_flags (h, buf);  }  if (h != NULL)  {    if (count)    {      (*count)++;      if (!ctx->quiet && ReadInc && ((*count % ReadInc) == 0 || *count == 1))	mutt_message (_("Reading %s... %d"), ctx->path, *count);    }    if (subdir)    {      snprintf (buf, sizeof (buf), "%s/%s", subdir, fname);      h->path = safe_strdup (buf);    }    else      h->path = safe_strdup (fname);    entry = safe_calloc (sizeof (struct maildir), 1);    entry->h = h;    entry->header_parsed = (ctx->magic == M_MH);#ifdef USE_INODESORT    entry->inode = inode;#endif /* USE_INODESORT */    **last = entry;    *last = &entry->next;    return 0;  }  return -1;}/* Ignore the garbage files.  A valid MH message consists of only * digits.  Deleted message get moved to a filename with a comma before * it. */int mh_valid_message (const char *s){  for (; *s; s++)  {    if (!isdigit ((unsigned char) *s))      return 0;  }  return 1;}static int maildir_parse_dir (CONTEXT * ctx, struct maildir ***last,			      const char *subdir, int *count){  DIR *dirp;  struct dirent *de;  char buf[_POSIX_PATH_MAX];  int is_old = 0;#ifdef USE_HCACHE  header_cache_t *hc = NULL;#endif  if (subdir)  {    snprintf (buf, sizeof (buf), "%s/%s", ctx->path, subdir);    is_old = (mutt_strcmp ("cur", subdir) == 0);  }  else    strfcpy (buf, ctx->path, sizeof (buf));  if ((dirp = opendir (buf)) == NULL)    return -1;#ifdef USE_HCACHE  if (ctx && ctx->magic == M_MH)    hc = mutt_hcache_open (HeaderCache, ctx->path);#endif  while ((de = readdir (dirp)) != NULL)  {    if ((ctx->magic == M_MH && !mh_valid_message (de->d_name))	|| (ctx->magic == M_MAILDIR && *de->d_name == '.'))      continue;    /* FOO - really ignore the return value? */    dprint (2,	    (debugfile, "%s:%d: parsing %s\n", __FILE__, __LINE__,	     de->d_name));    maildir_parse_entry (ctx, last, subdir, de->d_name, count, is_old, #if HAVE_DIRENT_D_INO			 de->d_ino#else			 0#endif#if USE_HCACHE			 , hc#endif			 );  }  closedir (dirp);#if USE_HCACHE  mutt_hcache_close (hc);#endif  return 0;}static int maildir_add_to_context (CONTEXT * ctx, struct maildir *md){  int oldmsgcount = ctx->msgcount;  while (md)  {    dprint (2, (debugfile, "%s:%d maildir_add_to_context(): Considering %s\n",		__FILE__, __LINE__, NONULL (md->canon_fname)));    if (md->h)    {      dprint (2,	      (debugfile,	       "%s:%d Adding header structure. Flags: %s%s%s%s%s\n", __FILE__,	       __LINE__, md->h->flagged ? "f" : "", md->h->deleted ? "D" : "",	       md->h->replied ? "r" : "", md->h->old ? "O" : "",	       md->h->read ? "R" : ""));      if (ctx->msgcount == ctx->hdrmax)	mx_alloc_memory (ctx);      ctx->hdrs[ctx->msgcount] = md->h;      ctx->hdrs[ctx->msgcount]->index = ctx->msgcount;      ctx->size +=	md->h->content->length + md->h->content->offset -	md->h->content->hdr_offset;      md->h = NULL;      ctx->msgcount++;    }    md = md->next;  }  if (ctx->msgcount > oldmsgcount)  {    mx_update_context (ctx, ctx->msgcount - oldmsgcount);    return 1;  }  return 0;}static int maildir_move_to_context (CONTEXT * ctx, struct maildir **md){  int r;  r = maildir_add_to_context (ctx, *md);  maildir_free_maildir (md);  return r;}#if USE_HCACHEstatic size_t maildir_hcache_keylen (const char *fn){  const char * p = strrchr (fn, ':');  return p ? (size_t) (p - fn) : mutt_strlen(fn);}#endif#ifdef USE_INODESORT/* * Merge two maildir lists according to the inode numbers. */static struct maildir*  maildir_merge_inode (struct maildir *left,					     struct maildir *right){  struct maildir* head;  struct maildir* tail;  if (left && right)   {    if (left->inode < right->inode)    {      head = left;      left = left->next;    }    else     {      head = right;      right = right->next;    }  }   else   {    if (left)       return left;    else       return right;  }      tail = head;  while (left && right)   {    if (left->inode < right->inode)     {      tail->next = left;      left = left->next;    }     else     {      tail->next = right;      right = right->next;    }    tail = tail->next;  }  if (left)   {    tail->next = left;  }  else  {    tail->next = right;  }  return head;}/* * Sort maildir list according to inode. */static struct maildir* maildir_sort_inode(struct maildir* list){  struct maildir* left = list;  struct maildir* right = list;  if (!list || !list->next)   {    return list;  }  list = list->next;  while (list && list->next)   {    right = right->next;    list = list->next->next;  }  list = right;  right = right->next;  list->next = 0;  left = maildir_sort_inode(left);  right = maildir_sort_inode(right);  return maildir_merge_inode(left, right);}#endif /* USE_INODESORT *//*  * This function does the second parsing pass for a maildir-style * folder. */void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md){  struct maildir *p;  char fn[_POSIX_PATH_MAX];  int count;#if USE_HCACHE  header_cache_t *hc = NULL;  void *data;  struct timeval *when = NULL;  struct stat lastchanged;  int ret;  hc = mutt_hcache_open (HeaderCache, ctx->path);#endif  for (p = md, count = 0; p; p = p->next, count++)  {    if (! (p && p->h && !p->header_parsed))      continue;    if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1))      mutt_message (_("Reading %s... %d"), ctx->path, count);#if USE_HCACHE    data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen);    when = (struct timeval *) data;#endif    snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);#if USE_HCACHE    if (option(OPTHCACHEVERIFY))      ret = stat(fn, &lastchanged);    else {      lastchanged.st_mtime = 0;      ret = 0;    }        if (data != NULL && !ret && lastchanged.st_mtime <= when->tv_sec)    {      p->h = mutt_hcache_restore ((unsigned char *)data, &p->h);      maildir_parse_flags (p->h, fn);    } else#endif    if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h))    {      p->header_parsed = 1;#if USE_HCACHE      mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen);#endif    } else      mutt_free_header (&p->h);#if USE_HCACHE    FREE(&data);#endif  }#if USE_HCACHE  mutt_hcache_close (hc);#endif}/* Read a MH/maildir style mailbox. * * args: *	ctx [IN/OUT]	context for this mailbox *	subdir [IN]	NULL for MH mailboxes, otherwise the subdir of the *			maildir mailbox to read from */int mh_read_dir (CONTEXT * ctx, const char *subdir){  struct maildir *md;  struct mh_sequences mhs;  struct maildir **last;  int count;  memset (&mhs, 0, sizeof (mhs));  maildir_update_mtime (ctx);  md = NULL;  last = &md;  count = 0;  if (maildir_parse_dir (ctx, &last, subdir, &count) == -1)    return -1;  if (ctx->magic == M_MH)  {    mh_read_sequences (&mhs, ctx->path);    mh_update_maildir (md, &mhs);    mhs_free_sequences (&mhs);  }#ifdef USE_INODESORT  md = maildir_sort_inode(md);#endif /* USE_INODESORT */  if (ctx->magic == M_MAILDIR)    maildir_delayed_parsing (ctx, md);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -