bail: safe_fclose (&msg->fp); if (cache->path) { unlink (cache->path); FREE (&cache->path); } return (-1);
int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno){  char seq[8];  char buf[LONG_STRING];  char path[_POSIX_PATH_MAX];  char *pc;  long bytes;  int pos, len;  IMAP_CACHE *cache;  /* see if we already have the message in our cache */  cache = &CTX_DATA->cache[ctx->hdrs[msgno]->index % IMAP_CACHE_LEN];  if (cache->path)  {    if (cache->index == ctx->hdrs[msgno]->index)    {      /* yes, so just return a pointer to the message */      if (!(msg->fp = fopen (cache->path, "r")))      {	mutt_perror (cache->path);	return (-1);      }      return 0;    }    else    {      /* clear the previous entry */      unlink (cache->path);      FREE (&cache->path);    }  }  mutt_message _("Fetching message...");  cache->index = ctx->hdrs[msgno]->index;  mutt_mktemp (path);  cache->path = safe_strdup (path);  if (!(msg->fp = safe_fopen (path, "w+")))  {    safe_free ((void **) &cache->path);    return (-1);  }  imap_make_sequence (seq, sizeof (seq));#if 0  snprintf (buf, sizeof (buf), "%s FETCH %d RFC822\r\n", seq,	    ctx->hdrs[msgno]->index + 1);#else  snprintf (buf, sizeof (buf), "%s UID FETCH %d RFC822\r\n", seq,	    HEADER_DATA(ctx->hdrs[msgno])->uid);#endif  mutt_socket_write (CTX_DATA->conn, buf);  do  {    if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)    {      return (-1);    }    if (buf[0] == '*')    {      pc = buf;      pc = imap_next_word (pc);      pc = imap_next_word (pc);      if (mutt_strncasecmp ("FETCH", pc, 5) == 0)      {	while (*pc)	{	  pc = imap_next_word (pc);	  if (pc[0] == '(')	    pc++;	  dprint (2, (debugfile, "Found FETCH word %s\n", pc));	  if (strncasecmp ("RFC822", pc, 6) == 0)	  {	    pc = imap_next_word (pc);	    if (imap_get_literal_count(pc, &bytes) < 0)	    {	      imap_error ("imap_fetch_message()", buf);	      return (-1);	    }	    for (pos = 0; pos < bytes; )	    {	      len = mutt_socket_read_line (buf, sizeof (buf), CTX_DATA->conn);	      if (len < 0)		return (-1);	      pos += len;	      fputs (buf, msg->fp);	      fputs ("\n", msg->fp);	    }	    if (mutt_socket_read_line (buf, sizeof (buf), CTX_DATA->conn) < 0)	    {	      return (-1);	    }	    pc = buf;	  }          /* UW-IMAP will provide a FLAGS update here if the FETCH causes a           * change (eg from \Unseen to \Seen).           * Uncommitted changes in mutt take precedence. If we decide to           * incrementally update flags later, this won't stop us syncing */          else if ((strncasecmp ("FLAGS", pc, 5) == 0) &&            !ctx->hdrs[msgno]->changed)          {	    IMAP_HEADER* newh;            HEADER* h = ctx->hdrs[msgno];            newh = msg_new_header ();            dprint (2, (debugfile, "imap_fetch_message: parsing FLAGS\n"));            if ((pc = msg_parse_flags (newh, pc)) == NULL)              return -1;	    /* this is less efficient than the code which used to be here,	     * but (1) this is only invoked when fetching messages, and (2)	     * this way, we can make sure that side effects of flag changes	     * are taken account of the proper way.	     */	    mutt_set_flag (ctx, h, M_NEW, 		    !(newh->read || newh->old || h->read || h->old));	    mutt_set_flag (ctx, h, M_OLD, newh->old);	    mutt_set_flag (ctx, h, M_READ, h->read || newh->read);	    mutt_set_flag (ctx, h, M_DELETE, h->deleted || newh->deleted);	    mutt_set_flag (ctx, h, M_FLAG, h->flagged || newh->flagged);	    mutt_set_flag (ctx, h, M_REPLIED, h->replied || newh->replied);            /* this message is now definitively *not* changed (mutt_set_flag             * marks things changed as a side-effect) */            h->changed = 0;            mutt_free_list (&(HEADER_DATA(h)->keywords));            HEADER_DATA(h)->keywords = newh->data->keywords;            safe_free ((void**) &newh);          }	}      }      else if (imap_handle_untagged (CTX_DATA, buf) != 0)	return -1;    }  }  while (mutt_strncmp (buf, seq, SEQLEN) != 0);  if (!imap_code (buf))    return -1;  /* Update the header information.  Previously, we only downloaded a   * portion of the headers, those required for the main display.   */  rewind (msg->fp);  mutt_free_envelope (&ctx->hdrs[msgno]->env);  ctx->hdrs[msgno]->env = mutt_read_rfc822_header (msg->fp, ctx->hdrs[msgno],0, 0);  ctx->hdrs[msgno]->lines = 0;  fgets (buf, sizeof (buf), msg->fp);  while (!feof (msg->fp))  {    ctx->hdrs[msgno]->lines++;    fgets (buf, sizeof (buf), msg->fp);  }  ctx->hdrs[msgno]->content->length = ftell (msg->fp) -                                         ctx->hdrs[msgno]->content->offset;  /* This needs to be done in case this is a multipart message */#ifdef HAVE_PGP  ctx->hdrs[msgno]->pgp = pgp_query (ctx->hdrs[msgno]->content);#endif /* HAVE_PGP */  mutt_clear_error();  rewind (msg->fp);  return 0;}