Blame view

mh/mh_sequence.c 3.91 KB
1
/* GNU Mailutils -- a suite of utilities for electronic mail
2 3
   Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation,
   Inc.
4 5 6

   GNU Mailutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 3, or (at your option)
8 9 10 11 12 13 14 15
   any later version.

   GNU Mailutils 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
16
   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
17 18 19 20

#include <mh.h>

static char *
21
private_sequence_name (const char *name)
22 23
{
  char *p;
24
  char *mbox_dir = mh_expand_name (NULL, mh_current_folder (), 0);
25
  mu_asprintf (&p, "atr-%s-%s", name, mbox_dir);
26 27 28 29
  free (mbox_dir);
  return p;
}

30
const char *
31
mh_seq_read (mu_mailbox_t mbox, const char *name, int flags)
32
{
33
  const char *value;
34 35 36 37 38 39 40 41

  if (flags & SEQ_PRIVATE)
    {
      char *p = private_sequence_name (name);
      value = mh_global_context_get (p, NULL);
      free (p);
    }
  else
42
    value = mh_global_sequences_get (mbox, name, NULL);
43 44 45 46
  return value;
}

static void
47
write_sequence (mu_mailbox_t mbox, const char *name, char *value, int private)
48 49 50 51 52 53 54 55
{
  if (private)
    {
      char *p = private_sequence_name (name);
      mh_global_context_set (p, value);
      free (p);
    }
  else
56
    mh_global_sequences_set (mbox, name, value);
57 58 59
}

static void
60
delete_sequence (mu_mailbox_t mbox, const char *name, int private)
61
{
62
  write_sequence (mbox, name, NULL, private);
63 64 65
}

void
66
mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, int flags)
67
{
68
  const char *value = mh_seq_read (mbox, name, flags);
69
  char *new_value, *p;
70
  const char *buf;
71
  size_t i, len;
72

73
  delete_sequence (mbox, name, !(flags & SEQ_PRIVATE));
74 75 76 77 78 79 80 81 82 83 84

  if (flags & SEQ_ZERO)
    value = NULL;
  
  if (value)
    len = strlen (value);
  else
    len = 0;
  len++;
  for (i = 0; i < mset->count; i++)
    {
85
      buf = mu_umaxtostr (0, mset->list[i]);
86 87 88 89 90 91 92 93 94 95 96 97
      len += strlen (buf) + 1;
    }

  new_value = xmalloc (len + 1);
  if (value)
    strcpy (new_value, value);
  else
    new_value[0] = 0;
  p = new_value + strlen (new_value);
  *p++ = ' ';
  for (i = 0; i < mset->count; i++)
    {
98
      p += sprintf (p, "%s", mu_umaxtostr (0, mset->list[i]));
99 100 101
      *p++ = ' ';
    }
  *p = 0;
102 103
  write_sequence (mbox, name, new_value, flags & SEQ_PRIVATE);
  /* FIXME
104
  if (mu_c_strcasecmp (name, "cur") == 0)
105
    current_message = strtoul (new_value, NULL, 0);
106
  */
107
  free (new_value);
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
}

static int
cmp_msgnum (const void *a, const void *b)
{
  const size_t *as = a;
  const size_t *bs = b;

  if (*as < *bs)
    return -1;
  if (*as > *bs)
    return 1;
  return 0;
}

int
124 125
mh_seq_delete (mu_mailbox_t mbox, const char *name,
	       mh_msgset_t *mset, int flags)
126
{
127
  const char *value = mh_seq_read (mbox, name, flags);
128
  char *new_val;
129
  char *p;
130 131
  size_t i, count;
  struct mu_wordsplit ws;
132 133 134 135
  
  if (!value)
    return 0;

136 137 138 139 140 141
  if (mu_wordsplit (value, &ws, MU_WRDSF_DEFFLAGS))
    {
      mu_error (_("cannot split line `%s': %s"), value,
		mu_wordsplit_strerror (&ws));
      return 0;
    }
142

143
  for (i = 0; i < ws.ws_wordc; i++)
144 145
    {
      char *p;
146
      size_t num = strtoul (ws.ws_wordv[i], &p, 10);
147 148 149 150 151 152 153

      if (*p)
	continue;

      if (bsearch (&num, mset->list, mset->count, sizeof (mset->list[0]),
		   cmp_msgnum))
	{
154 155
	  free (ws.ws_wordv[i]);
	  ws.ws_wordv[i] = NULL;
156 157 158
	}
    }

159 160
  new_val = xstrdup (value);
  p = new_val;
161
  count = 0;
162
  for (i = 0; i < ws.ws_wordc; i++)
163
    {
164
      if (ws.ws_wordv[i])
165
	{
166
	  strcpy (p, ws.ws_wordv[i]);
167 168 169 170 171 172
	  p += strlen (p);
	  *p++ = ' ';
	  count++;
	}
    }
  *p = 0;
173
  write_sequence (mbox, name, count > 0 ? new_val : NULL, flags & SEQ_PRIVATE);
174
  mu_wordsplit_free (&ws);
175
  free (new_val);
176 177 178 179
  
  return 0;
}