コード例 #1
0
ファイル: server.c プロジェクト: pacqu/final-1
int handle_request(int socket_id, struct user client) {
  int e;
  struct signal sig;

  e = fetch_a_message(socket_id, client.name, &sig);
  if (e < 0) return -1;

  switch (sig.type) {
  case DISCONNECT:
    running = 0;
    break;
  case MESSAGE:
    if (is_to(sig.body.message, client)) {
      e = write(socket_id, &sig, sizeof(sig));
      if (e < 0) return -1;
    } else if (is_from(sig.body.message, client)) {
      int to_pipe = open(sig.body.message.to.name, O_WRONLY | O_NONBLOCK);
      if (to_pipe < 0) return 0;

      e = write(to_pipe, &sig, sizeof(sig));
      if (e < 0) return -1;
      close(to_pipe);

      printf("<%s> said %s to <%s>\n", sig.body.message.from.name, sig.body.message.text, sig.body.message.to.name);
    }
    break;
  }

  return e;
}
コード例 #2
0
ファイル: copy.c プロジェクト: 0xAX/mutt
int
_mutt_append_message (CONTEXT *dest, FILE *fpin, CONTEXT *src, HEADER *hdr,
		      BODY *body, int flags, int chflags)
{
  char buf[STRING];
  MESSAGE *msg;
  int r;

  fseeko (fpin, hdr->offset, 0);
  if (fgets (buf, sizeof (buf), fpin) == NULL)
    return -1;

  if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0 : M_ADD_FROM)) == NULL)
    return -1;
  if (dest->magic == M_MBOX || dest->magic == M_MMDF)
    chflags |= CH_FROM | CH_FORCE_FROM;
  chflags |= (dest->magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
  r = _mutt_copy_message (msg->fp, fpin, hdr, body, flags, chflags);
  if (mx_commit_message (msg, dest) != 0)
    r = -1;

#ifdef USE_NOTMUCH
  if (hdr && msg->commited_path && dest->magic == M_MAILDIR && src->magic == M_NOTMUCH)
	  nm_update_filename(src, NULL, msg->commited_path, hdr);
#endif

  mx_close_message (&msg);
  return r;
}
コード例 #3
0
ファイル: attach.c プロジェクト: BackupTheBerlios/mutt-win32
/* returns 0 on success, -1 on error */
int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags, HEADER *hdr)
{
  if (fp)
  {
    
    /* recv mode */

    if(hdr &&
	m->hdr &&
	m->encoding != ENCBASE64 &&
	m->encoding != ENCQUOTEDPRINTABLE &&
	mutt_is_message_type(m->type, m->subtype))
    {
      /* message type attachments are written to mail folders. */

      char buf[HUGE_STRING];
      HEADER *hn;
      CONTEXT ctx;
      MESSAGE *msg;
      int chflags = 0;
      int r = -1;
      
      hn = m->hdr;
      hn->msgno = hdr->msgno; /* required for MH/maildir */
      hn->read = 1;

      fseeko (fp, m->offset, 0);
      if (fgets (buf, sizeof (buf), fp) == NULL)
	return -1;
      if (mx_open_mailbox(path, M_APPEND | M_QUIET, &ctx) == NULL)
	return -1;
      if ((msg = mx_open_new_message (&ctx, hn, is_from (buf, NULL, 0, NULL) ? 0 : M_ADD_FROM)) == NULL)
      {
	mx_close_mailbox(&ctx, NULL);
	return -1;
      }
      if (ctx.magic == M_MBOX || ctx.magic == M_MMDF)
	chflags = CH_FROM | CH_UPDATE_LEN;
      chflags |= (ctx.magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
      if (_mutt_copy_message (msg->fp, fp, hn, hn->content, 0, chflags) == 0 
	  && mx_commit_message (msg, &ctx) == 0)
	r = 0;
      else
	r = -1;

      mx_close_message (&msg);
      mx_close_mailbox (&ctx, NULL);
      return r;
    }
    else
    {
      /* In recv mode, extract from folder and decode */

      STATE s;

      memset (&s, 0, sizeof (s));
      s.flags |= M_CHARCONV;

      if ((s.fpout = mutt_save_attachment_open (path, flags)) == NULL)
      {
	mutt_perror ("fopen");
	mutt_sleep (2);
	return (-1);
      }
      fseeko ((s.fpin = fp), m->offset, 0);
      mutt_decode_attachment (m, &s);

      if (fclose (s.fpout) != 0)
      {
	mutt_perror ("fclose");
	mutt_sleep (2);
	return (-1);
      }
    }
  }
  else
  {
    /* In send mode, just copy file */

    FILE *ofp, *nfp;

    if ((ofp = fopen (m->filename, "r")) == NULL)
    {
      mutt_perror ("fopen");
      return (-1);
    }
    
    if ((nfp = mutt_save_attachment_open (path, flags)) == NULL)
    {
      mutt_perror ("fopen");
      safe_fclose (&ofp);
      return (-1);
    }

    if (mutt_copy_stream (ofp, nfp) == -1)
    {
      mutt_error _("Write fault!");
      safe_fclose (&ofp);
      safe_fclose (&nfp);
      return (-1);
    }
    safe_fclose (&ofp);
    safe_fclose (&nfp);
  }

  return 0;
}
コード例 #4
0
ファイル: mbox.c プロジェクト: kdave/neomutt
/**
 * mbox_parse_mailbox - Read a mailbox from disk
 * @param m Mailbox
 * @retval  0 Success
 * @retval -1 Error
 * @retval -2 Aborted
 *
 * Note that this function is also called when new mail is appended to the
 * currently open folder, and NOT just when the mailbox is initially read.
 *
 * NOTE: it is assumed that the mailbox being read has been locked before this
 * routine gets called.  Strange things could happen if it's not!
 */
static int mbox_parse_mailbox(struct Mailbox *m)
{
  if (!m)
    return -1;

  struct MboxAccountData *adata = mbox_adata_get(m);
  if (!adata)
    return -1;

  struct stat sb;
  char buf[8192], return_path[256];
  struct Email *e_cur = NULL;
  time_t t;
  int count = 0, lines = 0;
  LOFF_T loc;
  struct Progress progress;

  /* Save information about the folder at the time we opened it. */
  if (stat(m->path, &sb) == -1)
  {
    mutt_perror(m->path);
    return -1;
  }

  m->size = sb.st_size;
  mutt_file_get_stat_timespec(&m->mtime, &sb, MUTT_STAT_MTIME);
  mutt_file_get_stat_timespec(&adata->atime, &sb, MUTT_STAT_ATIME);

  if (!m->readonly)
    m->readonly = access(m->path, W_OK) ? true : false;

  if (!m->quiet)
  {
    char msgbuf[256];
    snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), m->path);
    mutt_progress_init(&progress, msgbuf, MUTT_PROGRESS_MSG, C_ReadInc, 0);
  }

  if (!m->emails)
  {
    /* Allocate some memory to get started */
    m->email_max = m->msg_count;
    m->msg_count = 0;
    m->msg_unread = 0;
    m->vcount = 0;
    mx_alloc_memory(m);
  }

  loc = ftello(adata->fp);
  while ((fgets(buf, sizeof(buf), adata->fp)) && (SigInt != 1))
  {
    if (is_from(buf, return_path, sizeof(return_path), &t))
    {
      /* Save the Content-Length of the previous message */
      if (count > 0)
      {
        struct Email *e = m->emails[m->msg_count - 1];
        if (e->content->length < 0)
        {
          e->content->length = loc - e->content->offset - 1;
          if (e->content->length < 0)
            e->content->length = 0;
        }
        if (!e->lines)
          e->lines = lines ? lines - 1 : 0;
      }

      count++;

      if (!m->quiet)
      {
        mutt_progress_update(&progress, count,
                             (int) (ftello(adata->fp) / (m->size / 100 + 1)));
      }

      if (m->msg_count == m->email_max)
        mx_alloc_memory(m);

      m->emails[m->msg_count] = mutt_email_new();
      e_cur = m->emails[m->msg_count];
      e_cur->received = t - mutt_date_local_tz(t);
      e_cur->offset = loc;
      e_cur->index = m->msg_count;

      e_cur->env = mutt_rfc822_read_header(adata->fp, e_cur, false, false);

      /* if we know how long this message is, either just skip over the body,
       * or if we don't know how many lines there are, count them now (this will
       * save time by not having to search for the next message marker).  */
      if (e_cur->content->length > 0)
      {
        LOFF_T tmploc;

        loc = ftello(adata->fp);

        /* The test below avoids a potential integer overflow if the
         * content-length is huge (thus necessarily invalid).  */
        tmploc = (e_cur->content->length < m->size) ?
                     (loc + e_cur->content->length + 1) :
                     -1;

        if ((tmploc > 0) && (tmploc < m->size))
        {
          /* check to see if the content-length looks valid.  we expect to
           * to see a valid message separator at this point in the stream */
          if ((fseeko(adata->fp, tmploc, SEEK_SET) != 0) ||
              !fgets(buf, sizeof(buf), adata->fp) ||
              !mutt_str_startswith(buf, "From ", CASE_MATCH))
          {
            mutt_debug(LL_DEBUG1, "bad content-length in message %d (cl=" OFF_T_FMT ")\n",
                       e_cur->index, e_cur->content->length);
            mutt_debug(LL_DEBUG1, "\tLINE: %s", buf);
            /* nope, return the previous position */
            if ((loc < 0) || (fseeko(adata->fp, loc, SEEK_SET) != 0))
            {
              mutt_debug(LL_DEBUG1, "#1 fseek() failed\n");
            }
            e_cur->content->length = -1;
          }
        }
        else if (tmploc != m->size)
        {
          /* content-length would put us past the end of the file, so it
           * must be wrong */
          e_cur->content->length = -1;
        }

        if (e_cur->content->length != -1)
        {
          /* good content-length.  check to see if we know how many lines
           * are in this message.  */
          if (e_cur->lines == 0)
          {
            int cl = e_cur->content->length;

            /* count the number of lines in this message */
            if ((loc < 0) || (fseeko(adata->fp, loc, SEEK_SET) != 0))
              mutt_debug(LL_DEBUG1, "#2 fseek() failed\n");
            while (cl-- > 0)
            {
              if (fgetc(adata->fp) == '\n')
                e_cur->lines++;
            }
          }

          /* return to the offset of the next message separator */
          if (fseeko(adata->fp, tmploc, SEEK_SET) != 0)
            mutt_debug(LL_DEBUG1, "#3 fseek() failed\n");
        }
      }

      m->msg_count++;

      if (!e_cur->env->return_path && return_path[0])
      {
        e_cur->env->return_path = mutt_addr_parse_list(e_cur->env->return_path, return_path);
      }

      if (!e_cur->env->from)
        e_cur->env->from = mutt_addr_copy_list(e_cur->env->return_path, false);

      lines = 0;
    }
    else
      lines++;

    loc = ftello(adata->fp);
  }

  /* Only set the content-length of the previous message if we have read more
   * than one message during _this_ invocation.  If this routine is called
   * when new mail is received, we need to make sure not to clobber what
   * previously was the last message since the headers may be sorted.  */
  if (count > 0)
  {
    struct Email *e = m->emails[m->msg_count - 1];
    if (e->content->length < 0)
    {
      e->content->length = ftello(adata->fp) - e->content->offset - 1;
      if (e->content->length < 0)
        e->content->length = 0;
    }

    if (!e->lines)
      e->lines = lines ? lines - 1 : 0;
  }

  if (SigInt == 1)
  {
    SigInt = 0;
    return -2; /* action aborted */
  }

  return 0;
}
コード例 #5
0
ファイル: mbox.c プロジェクト: kdave/neomutt
/**
 * mmdf_parse_mailbox - Read a mailbox in MMDF format
 * @param m Mailbox
 * @retval  0 Success
 * @retval -1 Failure
 * @retval -2 Aborted
 */
static int mmdf_parse_mailbox(struct Mailbox *m)
{
  if (!m)
    return -1;

  struct MboxAccountData *adata = mbox_adata_get(m);
  if (!adata)
    return -1;

  char buf[8192];
  char return_path[1024];
  int count = 0;
  int lines;
  time_t t;
  LOFF_T loc, tmploc;
  struct Email *e = NULL;
  struct stat sb;
  struct Progress progress;

  if (stat(m->path, &sb) == -1)
  {
    mutt_perror(m->path);
    return -1;
  }
  mutt_file_get_stat_timespec(&adata->atime, &sb, MUTT_STAT_ATIME);
  mutt_file_get_stat_timespec(&m->mtime, &sb, MUTT_STAT_MTIME);
  m->size = sb.st_size;

  buf[sizeof(buf) - 1] = '\0';

  if (!m->quiet)
  {
    char msgbuf[256];
    snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), m->path);
    mutt_progress_init(&progress, msgbuf, MUTT_PROGRESS_MSG, C_ReadInc, 0);
  }

  while (true)
  {
    if (!fgets(buf, sizeof(buf) - 1, adata->fp))
      break;

    if (SigInt == 1)
      break;

    if (mutt_str_strcmp(buf, MMDF_SEP) == 0)
    {
      loc = ftello(adata->fp);
      if (loc < 0)
        return -1;

      count++;
      if (!m->quiet)
        mutt_progress_update(&progress, count, (int) (loc / (m->size / 100 + 1)));

      if (m->msg_count == m->email_max)
        mx_alloc_memory(m);
      e = mutt_email_new();
      m->emails[m->msg_count] = e;
      e->offset = loc;
      e->index = m->msg_count;

      if (!fgets(buf, sizeof(buf) - 1, adata->fp))
      {
        /* TODO: memory leak??? */
        mutt_debug(LL_DEBUG1, "unexpected EOF\n");
        break;
      }

      return_path[0] = '\0';

      if (!is_from(buf, return_path, sizeof(return_path), &t))
      {
        if (fseeko(adata->fp, loc, SEEK_SET) != 0)
        {
          mutt_debug(LL_DEBUG1, "#1 fseek() failed\n");
          mutt_error(_("Mailbox is corrupt"));
          return -1;
        }
      }
      else
        e->received = t - mutt_date_local_tz(t);

      e->env = mutt_rfc822_read_header(adata->fp, e, false, false);

      loc = ftello(adata->fp);
      if (loc < 0)
        return -1;

      if ((e->content->length > 0) && (e->lines > 0))
      {
        tmploc = loc + e->content->length;

        if ((tmploc > 0) && (tmploc < m->size))
        {
          if ((fseeko(adata->fp, tmploc, SEEK_SET) != 0) ||
              !fgets(buf, sizeof(buf) - 1, adata->fp) ||
              (mutt_str_strcmp(MMDF_SEP, buf) != 0))
          {
            if (fseeko(adata->fp, loc, SEEK_SET) != 0)
              mutt_debug(LL_DEBUG1, "#2 fseek() failed\n");
            e->content->length = -1;
          }
        }
        else
          e->content->length = -1;
      }
      else
        e->content->length = -1;

      if (e->content->length < 0)
      {
        lines = -1;
        do
        {
          loc = ftello(adata->fp);
          if (loc < 0)
            return -1;
          if (!fgets(buf, sizeof(buf) - 1, adata->fp))
            break;
          lines++;
        } while (mutt_str_strcmp(buf, MMDF_SEP) != 0);

        e->lines = lines;
        e->content->length = loc - e->content->offset;
      }

      if (!e->env->return_path && return_path[0])
        e->env->return_path = mutt_addr_parse_list(e->env->return_path, return_path);

      if (!e->env->from)
        e->env->from = mutt_addr_copy_list(e->env->return_path, false);

      m->msg_count++;
    }
    else
    {
      mutt_debug(LL_DEBUG1, "corrupt mailbox\n");
      mutt_error(_("Mailbox is corrupt"));
      return -1;
    }
  }

  if (SigInt == 1)
  {
    SigInt = 0;
    return -2; /* action aborted */
  }

  return 0;
}
コード例 #6
0
ファイル: mbox.cpp プロジェクト: badeip/neomutt
int mmdf_parse_mailbox(CONTEXT *ctx)
{
    char buf[HUGE_STRING];
    char return_path[LONG_STRING];
    int count = 0, oldmsgcount = ctx->msgcount;
    int lines;
    time_t t;
    LOFF_T loc, tmploc;
    HEADER *hdr;
    struct stat sb;

#ifdef NFS_ATTRIBUTE_HACK
    struct utimbuf newtime;
#endif /* ifdef NFS_ATTRIBUTE_HACK */
    progress_t progress;
    char msgbuf[STRING];

    if (stat(ctx->path, &sb) == -1) {
        mutt_perror(ctx->path);
        return -1;
    }
    ctx->atime = sb.st_atime;
    ctx->mtime = sb.st_mtime;
    ctx->size = sb.st_size;

#ifdef NFS_ATTRIBUTE_HACK

    if (sb.st_mtime > sb.st_atime) {
        newtime.modtime = sb.st_mtime;
        newtime.actime = time(NULL);
        utime(ctx->path, &newtime);
    }
#endif /* ifdef NFS_ATTRIBUTE_HACK */

    buf[sizeof(buf) - 1] = 0;

    if (!ctx->quiet) {
        snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), ctx->path);
        mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG, ReadInc, 0);
    }

    FOREVER
    {
        if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
            break;

        if (mutt_strcmp(buf, MMDF_SEP) == 0) {
            loc = ftello(ctx->fp);

            count++;

            if (!ctx->quiet)
                mutt_progress_update(&progress, count,
                                     (int)(loc / (ctx->size / 100 + 1)));

            if (ctx->msgcount == ctx->hdrmax)
                mx_alloc_memory(ctx);
            ctx->hdrs[ctx->msgcount] = hdr = mutt_new_header();
            hdr->offset = loc;
            hdr->index = ctx->msgcount;

            if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL) {
                /* TODO: memory leak??? */
                dprint(1, "mmdf_parse_mailbox: unexpected EOF\n");
                break;
            }

            return_path[0] = 0;

            if (!is_from(buf, return_path, sizeof(return_path), &t)) {
                if (fseeko(ctx->fp, loc, SEEK_SET) != 0) {
                    dprint(1, "mmdf_parse_mailbox: fseek() failed\n");
                    mutt_error _("Mailbox is corrupt!");
                    return -1;
                }
            } else
                hdr->received = t - mutt_local_tz(t);

            hdr->env = mutt_read_rfc822_header(ctx->fp, hdr, 0, 0);

            loc = ftello(ctx->fp);

            if ((hdr->content->length > 0)
                && (hdr->lines > 0)) {
                tmploc = loc + hdr->content->length;

                if ((0 < tmploc)
                    && (tmploc < ctx->size)) {
                    if ((fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        || (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
                        || (mutt_strcmp(MMDF_SEP, buf) != 0)) {
                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0)
                            dprint(1, "mmdf_parse_mailbox: fseek() failed\n");
                        hdr->content->length = -1;
                    }
                } else
                    hdr->content->length = -1;
            } else
                hdr->content->length = -1;

            if (hdr->content->length < 0) {
                lines = -1;

                do {
                    loc = ftello(ctx->fp);

                    if (fgets(buf, sizeof(buf) - 1, ctx->fp) == NULL)
                        break;
                    lines++;
                } while (mutt_strcmp(buf, MMDF_SEP) != 0);

                hdr->lines = lines;
                hdr->content->length = loc - hdr->content->offset;
            }

            if (!hdr->env->return_path
                && return_path[0])
                hdr->env->return_path = rfc822_parse_adrlist(
                    hdr->env->return_path,
                    return_path);

            if (!hdr->env->from)
                hdr->env->from = rfc822_cpy_adr(hdr->env->return_path, 0);

            ctx->msgcount++;
        } else {
            dprint(1, "mmdf_parse_mailbox: corrupt mailbox!\n");
            mutt_error _("Mailbox is corrupt!");
            return -1;
        }
    }

    if (ctx->msgcount > oldmsgcount)
        mx_update_context(ctx, ctx->msgcount - oldmsgcount);

    return 0;
}
コード例 #7
0
ファイル: mbox.cpp プロジェクト: badeip/neomutt
/* Note that this function is also called when new mail is appended to the
 * currently open folder, and NOT just when the mailbox is initially read.
 *
 * NOTE: it is assumed that the mailbox being read has been locked before
 * this routine gets called.  Strange things could happen if it's not!
 */
int mbox_parse_mailbox(CONTEXT *ctx)
{
    struct stat sb;
    char buf[HUGE_STRING], return_path[STRING];
    HEADER *curhdr;
    time_t t;
    int count = 0, lines = 0;
    LOFF_T loc;

#ifdef NFS_ATTRIBUTE_HACK
    struct utimbuf newtime;
#endif /* ifdef NFS_ATTRIBUTE_HACK */
    progress_t progress;
    char msgbuf[STRING];

    /* Save information about the folder at the time we opened it. */
    if (stat(ctx->path, &sb) == -1) {
        mutt_perror(ctx->path);
        return -1;
    }

    ctx->size = sb.st_size;
    ctx->mtime = sb.st_mtime;
    ctx->atime = sb.st_atime;

#ifdef NFS_ATTRIBUTE_HACK

    if (sb.st_mtime > sb.st_atime) {
        newtime.modtime = sb.st_mtime;
        newtime.actime = time(NULL);
        utime(ctx->path, &newtime);
    }
#endif /* ifdef NFS_ATTRIBUTE_HACK */

    if (!ctx->readonly)
        ctx->readonly = access(ctx->path, W_OK) ? 1 : 0;

    if (!ctx->quiet) {
        snprintf(msgbuf, sizeof(msgbuf), _("Reading %s..."), ctx->path);
        mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG, ReadInc, 0);
    }

    loc = ftello(ctx->fp);

    while (fgets(buf, sizeof(buf), ctx->fp) != NULL) {
        if (is_from(buf, return_path, sizeof(return_path), &t)) {
            /* Save the Content-Length of the previous message */
            if (count > 0) {
#define PREV ctx->hdrs[ctx->msgcount - 1]

                if (PREV->content->length < 0) {
                    PREV->content->length = loc - PREV->content->offset - 1;

                    if (PREV->content->length < 0)
                        PREV->content->length = 0;
                }

                if (!PREV->lines)
                    PREV->lines = lines ? lines - 1 : 0;
            }

            count++;

            if (!ctx->quiet)
                mutt_progress_update(&progress, count,
                                     (int)(ftello(ctx->fp) /
                                           (ctx->size / 100 + 1)));

            if (ctx->msgcount == ctx->hdrmax)
                mx_alloc_memory(ctx);

            curhdr = ctx->hdrs[ctx->msgcount] = mutt_new_header();
            curhdr->received = t - mutt_local_tz(t);
            curhdr->offset = loc;
            curhdr->index = ctx->msgcount;

            curhdr->env = mutt_read_rfc822_header(ctx->fp, curhdr, 0, 0);

            /* if we know how long this message is, either just skip over the
               body,
             * or if we don't know how many lines there are, count them now
             *(this will
             * save time by not having to search for the next message marker).
             */
            if (curhdr->content->length > 0) {
                LOFF_T tmploc;

                loc = ftello(ctx->fp);
                tmploc = loc + curhdr->content->length + 1;

                if ((0 < tmploc)
                    && (tmploc < ctx->size)) {
                    /*
                     * check to see if the content-length looks valid.  we
                     *expect to
                     * to see a valid message separator at this point in the
                     *stream
                     */
                    if ((fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        || (fgets(buf, sizeof(buf), ctx->fp) == NULL)
                        || (mutt_strncmp("From ", buf, 5) != 0)) {
                        dprint(1, "mbox_parse_mailbox: bad content-length in message %d (cl="
                                OFF_T_FMT ")\n", curhdr->index, curhdr->content->length);
                        dprint(1, "\tLINE: %s", buf);

                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0) { /* nope,
                                                                      return the
                                                                      previous
                                                                      position
                                                                      */
                            dprint(1, "mbox_parse_mailbox: fseek() failed\n");
                        }
                        curhdr->content->length = -1;
                    }
                } else if (tmploc != ctx->size) {
                    /* content-length would put us past the end of the file, so
                       it
                     * must be wrong
                     */
                    curhdr->content->length = -1;
                }

                if (curhdr->content->length != -1) {
                    /* good content-length.  check to see if we know how many
                       lines
                     * are in this message.
                     */
                    if (curhdr->lines == 0) {
                        int cl = curhdr->content->length;

                        /* count the number of lines in this message */
                        if (fseeko(ctx->fp, loc, SEEK_SET) != 0)
                            dprint(1, "mbox_parse_mailbox: fseek() failed\n");

                        while (cl-- > 0) {
                            if (fgetc(ctx->fp) == '\n')
                                curhdr->lines++;
                        }
                    }

                    /* return to the offset of the next message separator */
                    if (fseeko(ctx->fp, tmploc, SEEK_SET) != 0)
                        dprint(1, "mbox_parse_mailbox: fseek() failed\n");
                }
            }

            ctx->msgcount++;

            if (!curhdr->env->return_path
                && return_path[0])
                curhdr->env->return_path = rfc822_parse_adrlist(
                    curhdr->env->return_path,
                    return_path);

            if (!curhdr->env->from)
                curhdr->env->from = rfc822_cpy_adr(curhdr->env->return_path, 0);


            lines = 0;
        } else
            lines++;

        loc = ftello(ctx->fp);
    }

    /*
     * Only set the content-length of the previous message if we have read more
     * than one message during _this_ invocation.  If this routine is called
     * when new mail is received, we need to make sure not to clobber what
     * previously was the last message since the headers may be sorted.
     */
    if (count > 0) {
        if (PREV->content->length < 0) {
            PREV->content->length = ftello(ctx->fp) - PREV->content->offset - 1;

            if (PREV->content->length < 0)
                PREV->content->length = 0;
        }

        if (!PREV->lines)
            PREV->lines = lines ? lines - 1 : 0;

        mx_update_context(ctx, count);
    }

    return 0;
}
コード例 #8
0
ファイル: editmsg.c プロジェクト: aschrab/mutt
static int edit_one_message (CONTEXT *ctx, HEADER *cur)
{
  char tmp[_POSIX_PATH_MAX];
  char buff[STRING];
  int omagic;
  int oerrno;
  int rc;

  unsigned short o_read;
  unsigned short o_old;

  int of, cf;
  
  CONTEXT tmpctx;
  MESSAGE *msg;

  FILE *fp = NULL;

  struct stat sb;
  time_t mtime = 0;
  
  mutt_mktemp (tmp, sizeof (tmp));

  omagic = DefaultMagic;
  DefaultMagic = MUTT_MBOX;

  rc = (mx_open_mailbox (tmp, MUTT_NEWFOLDER, &tmpctx) == NULL) ? -1 : 0;

  DefaultMagic = omagic;

  if (rc == -1)
  {
    mutt_error (_("could not create temporary folder: %s"), strerror (errno));
    return -1;
  }

  rc = mutt_append_message (&tmpctx, ctx, cur, 0, CH_NOLEN |
	((ctx->magic == MUTT_MBOX || ctx->magic == MUTT_MMDF) ? 0 : CH_NOSTATUS));
  oerrno = errno;

  mx_close_mailbox (&tmpctx, NULL);

  if (rc == -1)
  {
    mutt_error (_("could not write temporary mail folder: %s"), strerror (oerrno));
    goto bail;
  }

  if ((rc = stat (tmp, &sb)) == -1)
  {
    mutt_error (_("Can't stat %s: %s"), tmp, strerror (errno));
    goto bail;
  }

  /*
   * 2002-09-05 [email protected]
   * The file the user is going to edit is not a real mbox, so we need to
   * truncate the last newline in the temp file, which is logically part of
   * the message separator, and not the body of the message.  If we fail to
   * remove it, the message will grow by one line each time the user edits
   * the message.
   */
  if (sb.st_size != 0 && truncate (tmp, sb.st_size - 1) == -1)
  {
    mutt_error (_("could not truncate temporary mail folder: %s"),
		strerror (errno));
    goto bail;
  }

  mtime = mutt_decrease_mtime (tmp, &sb);

  mutt_edit_file (NONULL(Editor), tmp);

  if ((rc = stat (tmp, &sb)) == -1)
  {
    mutt_error (_("Can't stat %s: %s"), tmp, strerror (errno));
    goto bail;
  }
  
  if (sb.st_size == 0)
  {
    mutt_message (_("Message file is empty!"));
    rc = 1;
    goto bail;
  }

  if (sb.st_mtime == mtime)
  {
    mutt_message (_("Message not modified!"));
    rc = 1;
    goto bail;
  }

  if ((fp = fopen (tmp, "r")) == NULL)
  {
    rc = -1;
    mutt_error (_("Can't open message file: %s"), strerror (errno));
    goto bail;
  }

  if (mx_open_mailbox (ctx->path, MUTT_APPEND, &tmpctx) == NULL)
  {
    rc = -1;
    /* L10N: %s is from strerror(errno) */
    mutt_error (_("Can't append to folder: %s"), strerror (errno));
    goto bail;
  }

  of = 0;
  cf = ((tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF) ? 0 : CH_NOSTATUS);
  
  if (fgets (buff, sizeof (buff), fp) && is_from (buff, NULL, 0, NULL))
  {
    if (tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF)
      cf = CH_FROM | CH_FORCE_FROM;
  }
  else
    of = MUTT_ADD_FROM;

  /* 
   * XXX - we have to play games with the message flags to avoid
   * problematic behavior with maildir folders.
   *
   */

  o_read = cur->read; o_old = cur->old;
  cur->read = cur->old = 0;
  msg = mx_open_new_message (&tmpctx, cur, of);
  cur->read = o_read; cur->old = o_old;

  if (msg == NULL)
  {
    mutt_error (_("Can't append to folder: %s"), strerror (errno));
    mx_close_mailbox (&tmpctx, NULL);
    goto bail;
  }

  if ((rc = mutt_copy_hdr (fp, msg->fp, 0, sb.st_size, CH_NOLEN | cf, NULL)) == 0)
  {
    fputc ('\n', msg->fp);
    rc = mutt_copy_stream (fp, msg->fp);
  }

  rc = mx_commit_message (msg, &tmpctx);
  mx_close_message (&tmpctx, &msg);
  
  mx_close_mailbox (&tmpctx, NULL);
  
  bail:
  if (fp) safe_fclose (&fp);

  if (rc >= 0)
    unlink (tmp);

  if (rc == 0)
  {
    mutt_set_flag (Context, cur, MUTT_DELETE, 1);
    mutt_set_flag (Context, cur, MUTT_PURGE, 1);
    mutt_set_flag (Context, cur, MUTT_READ, 1);

    if (option (OPTDELETEUNTAG))
      mutt_set_flag (Context, cur, MUTT_TAG, 0);
  }
  else if (rc == -1)
    mutt_message (_("Error. Preserving temporary file: %s"), tmp);

    
  return rc;
}