source: trunk/third/nmh/sbr/seq_read.c @ 12455

Revision 12455, 5.6 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * seq_read.c -- read the .mh_sequence file and
4 *            -- initialize sequence information
5 *
6 * $Id: seq_read.c,v 1.1.1.1 1999-02-07 18:14:10 danw Exp $
7 */
8
9#include <h/mh.h>
10
11/*
12 * static prototypes
13 */
14static int seq_init (struct msgs *, char *, char *);
15static void seq_public (struct msgs *);
16static void seq_private (struct msgs *);
17
18
19/*
20 * Get the sequence information for this folder from
21 * .mh_sequence (or equivalent specified in .mh_profile)
22 * or context file (for private sequences).
23 */
24
25void
26seq_read (struct msgs *mp)
27{
28    /* sanity check - check that context has been read */
29    if (defpath == NULL)
30        adios (NULL, "oops, context hasn't been read yet");
31
32    /*
33     * Initialize the list of sequence names.  Go ahead and
34     * add the "cur" sequence to the list of sequences.
35     */
36    mp->msgattrs[0] = getcpy (current);
37    mp->msgattrs[1] = NULL;
38    make_all_public (mp);       /* initially, make all public */
39
40    /* If folder is empty, don't scan for sequence information */
41    if (mp->nummsg == 0)
42        return;
43
44    /* Initialize the public sequences */
45    seq_public (mp);
46
47    /* Initialize the private sequences */
48    seq_private (mp);
49}
50
51
52/*
53 * read folder's sequences file for public sequences
54 */
55
56static void
57seq_public (struct msgs *mp)
58{
59    int state;
60    char *cp, seqfile[PATH_MAX];
61    char name[NAMESZ], field[BUFSIZ];
62    FILE *fp;
63
64    /*
65     * If mh_seq == NULL (such as if nmh been compiled with
66     * NOPUBLICSEQ), or if *mh_seq == '\0' (the user has defined
67     * the "mh-sequences" profile entry, but left it empty),
68     * then just return, and do not initialize any public sequences.
69     */
70    if (mh_seq == NULL || *mh_seq == '\0')
71        return;
72
73    /* get filename of sequence file */
74    snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
75
76    if ((fp = fopen (seqfile, "r")) == NULL)
77        return;
78
79    /* Use m_getfld to scan sequence file */
80    for (state = FLD;;) {
81        switch (state = m_getfld (state, name, field, sizeof(field), fp)) {
82            case FLD:
83            case FLDPLUS:
84            case FLDEOF:
85                if (state == FLDPLUS) {
86                    cp = getcpy (field);
87                    while (state == FLDPLUS) {
88                        state = m_getfld (state, name, field, sizeof(field), fp);
89                        cp = add (field, cp);
90                    }
91                    seq_init (mp, getcpy (name), trimcpy (cp));
92                    free (cp);
93                } else {
94                    seq_init (mp, getcpy (name), trimcpy (field));
95                }
96                if (state == FLDEOF)
97                    break;
98                continue;
99
100            case BODY:
101            case BODYEOF:
102                adios (NULL, "no blank lines are permitted in %s", seqfile);
103                /* fall */
104
105            case FILEEOF:
106                break;
107
108            default:
109                adios (NULL, "%s is poorly formatted", seqfile);
110        }
111        break;  /* break from for loop */
112    }
113
114    fclose (fp);
115}
116
117
118/*
119 * Scan profile/context list for private sequences.
120 *
121 * We search the context list for all keys that look like
122 * "atr-seqname-folderpath", and add them as private sequences.
123 */
124
125static void
126seq_private (struct msgs *mp)
127{
128    int i, j, alen, plen;
129    char *cp;
130    struct node *np;
131
132    alen = strlen ("atr-");
133    plen = strlen (mp->foldpath) + 1;
134
135    for (np = m_defs; np; np = np->n_next) {
136        if (ssequal ("atr-", np->n_name)
137                && (j = strlen (np->n_name) - plen) > alen
138                && *(np->n_name + j) == '-'
139                && strcmp (mp->foldpath, np->n_name + j + 1) == 0) {
140            cp = getcpy (np->n_name + alen);
141            *(cp + j - alen) = '\0';
142            if ((i = seq_init (mp, cp, getcpy (np->n_field))) != -1)
143                make_seq_private (mp, i);
144        }
145    }
146}
147
148
149/*
150 * Add the name of sequence to the list of folder sequences.
151 * Then parse the list of message ranges for this
152 * sequence, and setup the various bit flags for each
153 * message in the sequence.
154 *
155 * Return internal index for the sequence if successful.
156 * Return -1 on error.
157 */
158
159static int
160seq_init (struct msgs *mp, char *name, char *field)
161{
162    int i, j, k, is_current;
163    char *cp, **ap;
164
165    /*
166     * Check if this is "cur" sequence,
167     * so we can do some special things.
168     */
169    is_current = !strcmp (current, name);
170
171    /*
172     * Search for this sequence name to see if we've seen
173     * it already.  If we've seen this sequence before,
174     * then clear the bit for this sequence from all the
175     * mesages in this folder.
176     */
177    for (i = 0; mp->msgattrs[i]; i++) {
178        if (!strcmp (mp->msgattrs[i], name)) {
179            for (j = mp->lowmsg; j <= mp->hghmsg; j++)
180                clear_sequence (mp, i, j);
181            break;
182        }
183    }
184
185    /* Return error, if too many sequences */
186    if (i >= NUMATTRS) {
187        free (name);
188        free (field);
189        return -1;
190    }
191
192    /*
193     * If we've already seen this sequence name, just free the
194     * name string.  Else add it to the list of sequence names.
195     */
196    if (mp->msgattrs[i]) {
197        free (name);
198    } else {
199        mp->msgattrs[i] = name;
200        mp->msgattrs[i + 1] = NULL;
201    }
202
203    /*
204     * Split up the different message ranges at whitespace
205     */
206    for (ap = brkstring (field, " ", "\n"); *ap; ap++) {
207        if ((cp = strchr(*ap, '-')))
208            *cp++ = '\0';
209        if ((j = m_atoi (*ap)) > 0) {
210            k = cp ? m_atoi (cp) : j;
211
212            /*
213             * Keep mp->curmsg and "cur" sequence in synch.  Unlike
214             * other sequences, this message doesn't need to exist.
215             * Think about the series of command (rmm; next) to
216             * understand why this can be the case.  But if it does
217             * exist, we will still set the bit flag for it like
218             * other sequences.
219             */
220            if (is_current)
221                mp->curmsg = j;
222            /*
223             * We iterate through messages in this range
224             * and flip on bit for this sequence.
225             */
226            for (; j <= k; j++) {
227                if (j >= mp->lowmsg && j <= mp->hghmsg && does_exist(mp, j))
228                    add_sequence (mp, i, j);
229            }
230        }
231    }
232
233    free (field);       /* free string containing message ranges */
234    return i;
235}
Note: See TracBrowser for help on using the repository browser.