Initial revision
[mmh] / sbr / seq_list.c
1
2 /*
3  * seq_list.c -- Get all messages in a sequence and return them
4  *            -- as a space separated list of message ranges.
5  *
6  * $Id$
7  */
8
9 #include <h/mh.h>
10
11 /* allocate this much buffer space at a time */
12 #define MAXBUFFER 1024
13
14 /* static buffer to collect the sequence line */
15 static char *buffer = NULL;
16 static int len = 0;
17
18
19 char *
20 seq_list(struct msgs *mp, char *seqname)
21 {
22     int i, j, seqnum;
23     char *bp;
24
25     /* On first invocation, allocate initial buffer space */
26     if (!buffer) {
27         len = MAXBUFFER;
28         if (!(buffer = malloc ((size_t) len)))
29             adios (NULL, "unable to malloc storage in seq_list");
30     }
31
32     /*
33      * Special processing for "cur" sequence.  We assume that the
34      * "cur" sequence and mp->curmsg are in sync (see seq_add.c).
35      * This is returned, even if message doesn't exist or the
36      * folder is empty.
37      */
38     if (!strcmp (current, seqname)) {
39         if (mp->curmsg) {       
40             sprintf(buffer, "%s", m_name(mp->curmsg));
41             return (buffer);
42         } else
43             return (NULL);
44     }
45
46     /* If the folder is empty, just return NULL */
47     if (mp->nummsg == 0)
48         return NULL;
49
50     /* Get the index of the sequence */
51     if ((seqnum = seq_getnum (mp, seqname)) == -1)
52         return NULL;
53
54     bp = buffer;
55
56     for (i = mp->lowmsg; i <= mp->hghmsg; ++i) {
57         /*
58          * If message doesn't exist, or isn't in
59          * the sequence, then continue.
60          */
61         if (!does_exist(mp, i) || !in_sequence(mp, seqnum, i))
62             continue;
63
64         /*
65          * See if we need to enlarge buffer.  Since we don't know
66          * exactly how many character this particular message range
67          * will need, we enlarge the buffer if we are within
68          * 50 characters of the end.
69          */
70         if (bp - buffer > len - 50) {
71             char *newbuf;
72
73             len += MAXBUFFER;
74             if (!(newbuf = realloc (buffer, (size_t) len)))
75                 adios (NULL, "unable to realloc storage in seq_list");
76             bp = newbuf + (bp - buffer);
77             buffer = newbuf;
78         }
79
80         /*
81          * If this is not the first message range in
82          * the list, first add a space.
83          */
84         if (bp > buffer)
85             *bp++ = ' ';
86
87         sprintf(bp, "%s", m_name(i));
88         bp += strlen(bp);
89         j = i;                  /* Remember beginning of message range */
90
91         /*
92          * Scan to the end of this message range
93          */
94         for (++i; i <= mp->hghmsg && does_exist(mp, i) && in_sequence(mp, seqnum, i);
95              ++i)
96             ;
97
98         if (i - j > 1) {
99             sprintf(bp, "-%s", m_name(i - 1));
100             bp += strlen(bp);
101         }
102     }
103     return (bp > buffer? buffer : NULL);
104 }