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

📄 mh.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
  maildir_move_to_context (ctx, &md);  return 0;}/* read a maildir style mailbox */int maildir_read_dir (CONTEXT * ctx){  /* maildir looks sort of like MH, except that there are two subdirectories   * of the main folder path from which to read messages   */  if (mh_read_dir (ctx, "new") == -1 || mh_read_dir (ctx, "cur") == -1)    return (-1);  return 0;}/* * Open a new (temporary) message in an MH folder. */int mh_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr){  return mh_mkstemp (dest, &msg->fp, &msg->path);}int ch_compar (const void *a, const void *b){  return (int)( *((const char *) a) - *((const char *) b));}static void maildir_flags (char *dest, size_t destlen, HEADER * hdr){  *dest = '\0';  /*   * The maildir specification requires that all files in the cur   * subdirectory have the :unique string appeneded, regardless of whether   * or not there are any flags.  If .old is set, we know that this message   * will end up in the cur directory, so we include it in the following   * test even though there is no associated flag.   */    if (hdr && (hdr->flagged || hdr->replied || hdr->read || hdr->deleted || hdr->old || hdr->maildir_flags))  {    char tmp[LONG_STRING];    snprintf (tmp, sizeof (tmp),	      "%s%s%s%s%s",	      hdr->flagged ? "F" : "",	      hdr->replied ? "R" : "",	      hdr->read ? "S" : "", hdr->deleted ? "T" : "",	      NONULL(hdr->maildir_flags));    if (hdr->maildir_flags)      qsort (tmp, strlen (tmp), 1, ch_compar);    snprintf (dest, destlen, ":2,%s", tmp);  }}/* * Open a new (temporary) message in a maildir folder. *  * Note that this uses _almost_ the maildir file name format, but * with a {cur,new} prefix. * */int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr){  int fd;  char path[_POSIX_PATH_MAX];  char suffix[16];  char subdir[16];  if (hdr)  {    short deleted = hdr->deleted;    hdr->deleted = 0;    maildir_flags (suffix, sizeof (suffix), hdr);    hdr->deleted = deleted;  }  else    *suffix = '\0';  if (hdr && (hdr->read || hdr->old))    strfcpy (subdir, "cur", sizeof (subdir));  else    strfcpy (subdir, "new", sizeof (subdir));  FOREVER  {    snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%ld.%u_%d.%s%s",	      dest->path, subdir, time (NULL), (unsigned int)getpid (),	      Counter++, NONULL (Hostname), suffix);    dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n",		path));    if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1)    {      if (errno != EEXIST)      {	mutt_perror (path);	return -1;      }    }    else    {      dprint (2, (debugfile, "maildir_open_new_message (): Success.\n"));      msg->path = safe_strdup (path);      break;    }  }  if ((msg->fp = fdopen (fd, "w")) == NULL)  {    FREE (&msg->path);    close (fd);    unlink (path);    return (-1);  }  return 0;}/* * Commit a message to a maildir folder. *  * msg->path contains the file name of a file in tmp/. We take the * flags from this file's name.  * * ctx is the mail folder we commit to. *  * hdr is a header structure to which we write the message's new * file name.  This is used in the mh and maildir folder synch * routines.  When this routine is invoked from mx_commit_message, * hdr is NULL.  * * msg->path looks like this: *  *    tmp/{cur,new}.mutt-HOSTNAME-PID-COUNTER:flags *  * See also maildir_open_new_message(). *  */int maildir_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr){  char subdir[4];  char suffix[16];  char path[_POSIX_PATH_MAX];  char full[_POSIX_PATH_MAX];  char *s;  if (safe_fclose (&msg->fp) != 0)    return -1;  /* extract the subdir */  s = strrchr (msg->path, '/') + 1;  strfcpy (subdir, s, 4);  /* extract the flags */  if ((s = strchr (s, ':')))    strfcpy (suffix, s, sizeof (suffix));  else    suffix[0] = '\0';  /* construct a new file name. */  FOREVER  {    snprintf (path, _POSIX_PATH_MAX, "%s/%ld.%u_%d.%s%s", subdir,	      time (NULL), (unsigned int)getpid (), Counter++, 	      NONULL (Hostname), suffix);    snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path);    dprint (2, (debugfile, "maildir_commit_message (): renaming %s to %s.\n",		msg->path, full));    if (safe_rename (msg->path, full) == 0)    {      if (hdr)	mutt_str_replace (&hdr->path, path);      FREE (&msg->path);      /*       * Adjust the mtime on the file to match the time at which this       * message was received.  Currently this is only set when copying       * messages between mailboxes, so we test to ensure that it is       * actually set.       */      if (msg->received)      {	struct utimbuf ut;	ut.actime = msg->received;	ut.modtime = msg->received;	if (utime (full, &ut))	{	  mutt_perror (_("maildir_commit_message(): unable to set time on file"));	  return -1;	}      }      return 0;    }    else if (errno != EEXIST)    {      mutt_perror (ctx->path);      return -1;    }  }}/*  * commit a message to an MH folder. *  */static int _mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr,			       short updseq){  DIR *dirp;  struct dirent *de;  char *cp, *dep;  unsigned int n, hi = 0;  char path[_POSIX_PATH_MAX];  char tmp[16];  if (safe_fclose (&msg->fp) != 0)    return -1;  if ((dirp = opendir (ctx->path)) == NULL)  {    mutt_perror (ctx->path);    return (-1);  }  /* figure out what the next message number is */  while ((de = readdir (dirp)) != NULL)  {    dep = de->d_name;    if (*dep == ',')      dep++;    cp = dep;    while (*cp)    {      if (!isdigit ((unsigned char) *cp))	break;      cp++;    }    if (!*cp)    {      n = atoi (dep);      if (n > hi)	hi = n;    }  }  closedir (dirp);  /*    * Now try to rename the file to the proper name.   *    * Note: We may have to try multiple times, until we find a free   * slot.   */  FOREVER  {    hi++;    snprintf (tmp, sizeof (tmp), "%d", hi);    snprintf (path, sizeof (path), "%s/%s", ctx->path, tmp);    if (safe_rename (msg->path, path) == 0)    {      if (hdr)	mutt_str_replace (&hdr->path, tmp);      FREE (&msg->path);      break;    }    else if (errno != EEXIST)    {      mutt_perror (ctx->path);      return -1;    }  }  if (updseq)    mh_sequences_add_one (ctx, hi, !msg->flags.read, msg->flags.flagged,			  msg->flags.replied);  return 0;}int mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr){  return _mh_commit_message (ctx, msg, hdr, 1);}/* Sync a message in an MH folder. *  * This code is also used for attachment deletion in maildir * folders. */static int mh_rewrite_message (CONTEXT * ctx, int msgno){  HEADER *h = ctx->hdrs[msgno];  MESSAGE *dest;  int rc;  short restore = 1;  char oldpath[_POSIX_PATH_MAX];  char newpath[_POSIX_PATH_MAX];  char partpath[_POSIX_PATH_MAX];  long old_body_offset = h->content->offset;  long old_body_length = h->content->length;  long old_hdr_lines = h->lines;  if ((dest = mx_open_new_message (ctx, h, 0)) == NULL)    return -1;  if ((rc = mutt_copy_message (dest->fp, ctx, h,			       M_CM_UPDATE, CH_UPDATE | CH_UPDATE_LEN)) == 0)  {    snprintf (oldpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path);    strfcpy (partpath, h->path, _POSIX_PATH_MAX);    if (ctx->magic == M_MAILDIR)      rc = maildir_commit_message (ctx, dest, h);    else      rc = _mh_commit_message (ctx, dest, h, 0);    mx_close_message (&dest);    if (rc == 0)    {      unlink (oldpath);      restore = 0;    }    /*      * Try to move the new message to the old place.     * (MH only.)     *     * This is important when we are just updating flags.     *     * Note that there is a race condition against programs which     * use the first free slot instead of the maximum message     * number.  Mutt does _not_ behave like this.     *      * Anyway, if this fails, the message is in the folder, so     * all what happens is that a concurrently runnung mutt will     * lose flag modifications.     */    if (ctx->magic == M_MH && rc == 0)    {      snprintf (newpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path);      if ((rc = safe_rename (newpath, oldpath)) == 0)	mutt_str_replace (&h->path, partpath);    }  }  else    mx_close_message (&dest);  if (rc == -1 && restore)  {    h->content->offset = old_body_offset;    h->content->length = old_body_length;    h->lines = old_hdr_lines;  }  mutt_free_body (&h->content->parts);  return rc;}static int mh_sync_message (CONTEXT * ctx, int msgno){  HEADER *h = ctx->hdrs[msgno];  if (h->attach_del ||       (h->env && (h->env->refs_changed || h->env->irt_changed)))    if (mh_rewrite_message (ctx, msgno) != 0)      return -1;  return 0;}static int maildir_sync_message (CONTEXT * ctx, int msgno){  HEADER *h = ctx->hdrs[msgno];  if (h->attach_del ||       (h->env && (h->env->refs_changed || h->env->irt_changed)))  {    /* when doing attachment deletion/rethreading, fall back to the MH case. */    if (mh_rewrite_message (ctx, msgno) != 0)      return (-1);  }  else  {    /* we just have to rename the file. */    char newpath[_POSIX_PATH_MAX];    char partpath[_POSIX_PATH_MAX];    char fullpath[_POSIX_PATH_MAX];    char oldpath[_POSIX_PATH_MAX];    char suffix[16];    char *p;    if ((p = strrchr (h->path, '/')) == NULL)    {      dprint (1,	      (debugfile,	       "maildir_sync_message: %s: unable to find subdir!\n",	       h->path));      return (-1);    }    p++;    strfcpy (newpath, p, sizeof (newpath));    /* kill the previous flags */    if ((p = strchr (newpath, ':')) != NULL)      *p = 0;    maildir_flags (suffix, sizeof (suffix), h);    snprintf (partpath, sizeof (partpath), "%s/%s%s",	      (h->read || h->old) ? "cur" : "new", newpath, suffix);    snprintf (fullpath, sizeof (fullpath), "%s/%s", ctx->path, partpath);    snprintf (oldpath, sizeof (oldpath), "%s/%s", ctx->path, h->path);    if (mutt_strcmp (fullpath, oldpath) == 0)    {      /* message hasn't really changed */      return 0;    }    /* record that the message is possibly marked as trashed on disk */    h->trash = h->deleted;    if (rename (oldpath, fullpath) != 0)    {      mutt_perror ("rename");      return (-1);    }    mutt_str_replace (&h->path, partpath);  }  return (0);}int mh_sync_mailbox (CONTEXT * ctx, int *index_hint){  char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];  int i, j;#if USE_HCACHE  header_cache_t *hc = NULL;#endif /* USE_HCACHE */  if (ctx->magic == M_MH)    i = mh_check_mailbox (ctx, index_hint);  else     i = maildir_check_mailbox (ctx, index_hint);        if (i != 0)    return i;#if USE_HCACHE  if (ctx->magic == M_MAILDIR || ctx->magic == M_MH)    hc = mutt_hcache_open(HeaderCache, ctx->path);#endif /* USE_HCACHE */  for (i = 0; i < ctx->msgcount; i++)  {    if (ctx->hdrs[i]->deleted	&& (ctx->magic != M_MAILDIR || !option (OPTMAILDIRTRASH)))    {      snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path);      if (ctx->magic == M_MAILDIR	  || (option (OPTMHPURGE) && ctx->magic == M_MH))      {#if USE_HCACHE        if (ctx->magic == M_MAILDIR)          mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen);	else if (ctx->magic == M_MH)	  mutt_hcache_delete (hc, ctx->hdrs[i]->path, strlen);#endif /* USE_HCACHE */	unlink (path);      }      else if (ctx->magic == M_MH)      {	/* MH just moves files out of the way when you delete them */	if (*ctx->hdrs[i]->path != ',')	{	  snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path,		    ctx->hdrs[i]->path);	  unlink (tmp);	  rename (path, tmp);	}      }    }    else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del ||	     (ctx->magic == M_MAILDIR	      && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash)	      && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash)))    {      if (ctx->magic == M_MAILDIR)      {	if (maildir_sync_message (ctx, i) == -1)	  goto err;      }      else      {	if (mh_sync_message (ctx, i) == -1)	  goto err;      }

⌨️ 快捷键说明

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