Logo Search packages:      
Sourcecode: af version File versions  Download package

killbuf.c

/* Killbuf.c - Kill buffer handling for af.
   Copyright (C) 1990 - 2002 Malc Arnold.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <stdio.h>
#include "af.h"
#include "killbuf.h"
#include "keyseq.h"
#include "functions.h"
#include "variable.h"
#include "tags.h"
#include STRING_HDR

/****************************************************************************/
/* RCS info */

#ifndef lint
static char *RcsId = "$Id: killbuf.c,v 2.4 2002/08/21 23:54:48 malc Exp $";
static char *KillbufId = KILLBUFID;
#endif /* ! lint */

/****************************************************************************/
/* Global function declarations */

extern char *xmalloc(), *xstrdup();
extern int get_vval(), set_tags();
extern void disp_kill(), free_messages();
extern void set_sys_tags(), mask_tags();
extern void free_tlist();
extern TEXTLINE *copy_text();
extern TAG_LIST *taglist();

/* Local function declarations */

MESSAGE *copy_message_list();
static void do_kill(), add_killbuf();
static MESSAGE *cp_message();

/****************************************************************************/
/* The static kill ring and its size */

static KILLBUF *killbuf = NULL;
static int ring_size = 0;

/****************************************************************************/
void new_killbuf()
{
      /* Set up a new kill buffer in the ring */

      KILLBUF *k;

      /* Is the kill ring as large as it can get? */

      if (killbuf == NULL || ring_size < get_vval(V_KILL_RING)) {
            /* Add a new entry to the kill ring */

            k = (KILLBUF *) xmalloc(sizeof(KILLBUF));
            k->prev = (killbuf != NULL) ? killbuf : k;
            k->next = (killbuf != NULL) ? killbuf->next : k;
            k->prev->next = k->next->prev = k;
            k->messages = NULL;
            ring_size++;
            killbuf = k;
      } else {
            /* Clear and use the next kill ring entry */

            killbuf = killbuf->next;
            free_messages(killbuf->messages);
            killbuf->messages = NULL;
      }

      return;
}
/****************************************************************************/
void kill_message(buffer, message, prepend)
MAILBUF *buffer;
MESSAGE *message;
int prepend;
{
      /* Kill the message and add it to the kill buffer */

      do_kill(buffer, message, TRUE, prepend);
      return;
}
/****************************************************************************/
void copy_message(message)
MESSAGE *message;
{
      /* Copy the message into the kill buffer */

      add_killbuf(cp_message(message, FALSE), FALSE);
      return;
}
/****************************************************************************/
void del_message(buffer, message)
MAILBUF *buffer;
MESSAGE *message;
{
      /* Delete the message without adding it to the kill buffer */

      do_kill(buffer, message, FALSE, FALSE);
      return;
}
/****************************************************************************/
MESSAGE *get_killbuf()
{
      /* Return the kill buffer for a yank or NULL if it's empty */

      return((killbuf != NULL) ?
             copy_message_list(killbuf->messages) : NULL);
}
/****************************************************************************/
void pop_killbuf(no_pops, forwards)
int no_pops, forwards;
{
      /* Pop the kill ring the specified number of times */

      while (no_pops-- && killbuf != NULL) {
            killbuf = (forwards) ? killbuf->next : killbuf->prev;
      }
      return;
}
/****************************************************************************/
MESSAGE *copy_message_list(messages)
MESSAGE *messages;
{
      /* Return an allocated copy of a list of messages */

      MESSAGE *message, *m, *list;

      /* Copy the first message into the list */

      m = list = cp_message(messages, TRUE);

      /* Now copy the remaining messages */

      for (message = messages->next; message != NULL &&
           message->text != NULL; message = message->next) {
            /* Copy this message across */

            m->next = cp_message(message, TRUE);
            m->next->prev = m;
            m = m->next;
      }

      /* Now return the copied messages */

      return(list);
}
/****************************************************************************/
MESSAGE *copy_one_message(message)
MESSAGE *message;
{
      /* Return an allocated copy of a single message */

      MESSAGE *new_message;

      /* Copy the message and clear the pointers */

      new_message = cp_message(message, TRUE);
      new_message->prev = new_message->next = NULL;

      /* And return the copy of the message */

      return(new_message);
}
/****************************************************************************/
static void do_kill(buffer, message, save, prepend)
MAILBUF *buffer;
MESSAGE *message;
int save, prepend;
{
      /* Handle killing of messages from buffers */

      /* Update the windows for after the kill */

      disp_kill(buffer, message);

      /* Check if we are deleting at the start of the list */

      if (buffer->messages == message) {
            buffer->messages = message->next;
      }

      /* Do the deletion */

      if ((message->next->prev = message->prev) != NULL) {
            message->prev->next = message->next;
      }
      buffer->no_msgs--;

      /* Add the message to the kill buffer or free it */

      message->prev = message->next = NULL;
      if (save) {
            add_killbuf(message, prepend);
      } else {
            free_messages(message);
      }

      return;
}
/****************************************************************************/
static void add_killbuf(message, prepend)
MESSAGE *message;
int prepend;
{
      /* Add message to the current kill buffer */

      static MESSAGE *last_kbuf;

      /* May need to append or prepend the list */

      if (killbuf->messages == NULL) {
            /* Set the kill buffer to message */

            killbuf->messages = last_kbuf = message;
      } else if (prepend) {
            /* Prepend message to the kill buffer */

            message->next = killbuf->messages;
            killbuf->messages->prev = message;
            killbuf->messages = message;
      } else {
            /* Append the list to the kill buffer */

            last_kbuf->next = message;
            message->prev = last_kbuf;
            last_kbuf = message;
      }

      return;
}
/****************************************************************************/
static MESSAGE *cp_message(message, persistent)
MESSAGE *message;
int persistent;
{
      /* Return an allocated copy of message */

      int ref;
      MESSAGE *buf;
      TAG_LIST *tlist;

      /* Allocate space for the message */

      buf = (MESSAGE *) xmalloc(sizeof(MESSAGE));

      /* Copy the basic information */

      buf->from = xstrdup(message->from);
      buf->addr = xstrdup(message->from);
      buf->subject = xstrdup(message->subject);
      buf->reply = (message->reply != NULL)
            ? xstrdup(message->reply) : NULL;
      buf->group = (message->group != NULL)
            ? xstrdup(message->group) : NULL;
      buf->cc = (message->cc != NULL)
            ? xstrdup(message->cc) : NULL;

      /* Copy the MIME information */

      buf->contype = (message->contype != NULL)
            ? xstrdup(message->contype) : NULL;
      buf->encoding = (message->encoding != NULL)
            ? xstrdup(message->encoding) : NULL;
      buf->charset = (message->charset != NULL)
            ? xstrdup(message->charset) : NULL;
      buf->description = (message->description != NULL)
            ? xstrdup(message->description) : NULL;
      buf->filename = (message->filename != NULL)
            ? xstrdup(message->filename) : NULL;

      /* Copy the date if there is one */

      if (message->date != NULL) {
            buf->date = (DATEZONE *) xmalloc(sizeof(DATEZONE));
            buf->date->d_date = message->date->d_date;
            buf->date->d_zone = message->date->d_zone;
      } else {
            buf->date = NULL;
      }

      /* Copy the references */

      for (ref = 0; ref < NO_REFERENCES; ref++) {
            buf->refs[ref] = (message->refs[ref] != NULL)
                  ? xstrdup(message->refs[ref]) : NULL;
      }

      /* Copy the position in the buffer and network ID */

      buf->pos = message->pos;
      buf->id = (message->id != NULL) ? xstrdup(message->id) : NULL;

#ifdef MTA_CONTENT_LENGTH
      /* Copy the message's length */

      buf->length = message->length;
#endif /* MTA_CONTENT_LENGTH */

      /* Set the message's (persistent?) tags */

      buf->user_tags = NULL;

      if (persistent) {
            tlist = taglist(message->user_tags, TL_SET);
            mask_tags(tlist);
            (void) set_tags(buf, tlist);
            free_tlist(tlist);
      } else if (message->user_tags != NULL) {
            buf->user_tags = xstrdup(message->user_tags);
      }

      /* The copied message must be visible, unprocessed, and undeleted */

      buf->visible = TRUE;
      buf->processed = FALSE;
      buf->deleted = FALSE;

      /* Copy the message's status across */

      buf->bad = message->bad;
      buf->textual = message->textual;
      buf->multipart = message->multipart;
      buf->alternative = message->alternative;
      buf->parallel = message->parallel;
      buf->viewable = message->viewable;
      buf->decodable = message->decodable;
      buf->attachment = message->attachment;
      buf->new = message->new;
      buf->read = message->read;
      buf->replied = message->replied;
      buf->forwarded = message->forwarded;
      buf->saved = message->saved;
      buf->printed = message->printed;

      /* Set the message's system tags */

      buf->sys_tags = NULL;
      set_sys_tags(buf);

      /* And finally, zero the list data */

      buf->prev = buf->next = NULL;

      /* Now copy the message's text */

      buf->text = copy_text(message->text);

      /* All done; return the new message */

      return(buf);
}
/****************************************************************************/

Generated by  Doxygen 1.6.0   Back to index