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