New changes: Sender: cannot be blank, Sender: always overrides From:
[mmh] / sbr / seq_save.c
1
2 /*
3  * seq_save.c -- 1) synchronize sequences
4  *            -- 2) save public sequences
5  *
6  * This code is Copyright (c) 2002, by the authors of nmh.  See the
7  * COPYRIGHT file in the root directory of the nmh distribution for
8  * complete copyright information.
9  */
10
11 #include <h/mh.h>
12 #include <h/signals.h>
13
14
15 /*
16  * 1.  If sequence is public and folder is readonly,
17  *     then change it to be private
18  * 2a. If sequence is public, then add it to the sequences file
19  *     in folder (name specified by mh-sequences profile entry).
20  * 2b. If sequence is private, then add it to the
21  *     context file.
22  */
23
24 void
25 seq_save (struct msgs *mp)
26 {
27     int i;
28     char flags, *cp, attr[BUFSIZ], seqfile[PATH_MAX];
29     FILE *fp;
30     sigset_t set, oset;
31
32     /* check if sequence information has changed */
33     if (!(mp->msgflags & SEQMOD))
34         return;
35     mp->msgflags &= ~SEQMOD;
36
37     fp = NULL;
38     flags = mp->msgflags;       /* record folder flags */
39
40     /*
41      * If no mh-sequences file is defined, or if a mh-sequences file
42      * is defined but empty (*mh_seq == '\0'), then pretend folder
43      * is readonly.  This will force all sequences to be private.
44      */
45     if (mh_seq == NULL || *mh_seq == '\0')
46         set_readonly (mp);
47     else
48         snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
49
50     for (i = 0; mp->msgattrs[i]; i++) {
51         snprintf (attr, sizeof(attr), "atr-%s-%s", mp->msgattrs[i], mp->foldpath);
52
53         /* get space separated list of sequence ranges */
54         if (!(cp = seq_list(mp, mp->msgattrs[i]))) {
55             context_del (attr);                 /* delete sequence from context */
56             continue;
57         }
58
59         if (is_readonly(mp) || is_seq_private(mp, i)) {
60 priv:
61             /*
62              * sequence is private
63              */
64             context_replace (attr, cp);         /* update sequence in context   */
65         } else {
66             /*
67              * sequence is public
68              */
69             context_del (attr);                 /* delete sequence from context */
70
71             if (!fp) {
72                 /*
73                  * Attempt to open file for public sequences.
74                  * If that fails (probably because folder is
75                  * readonly), then make sequence private.
76                  */
77                 if ((fp = lkfopen (seqfile, "w")) == NULL
78                         && (unlink (seqfile) == -1 ||
79                             (fp = lkfopen (seqfile, "w")) == NULL)) {
80                     admonish (attr, "unable to write");
81                     goto priv;
82                 }
83
84                 /* block a few signals */
85                 sigemptyset (&set);
86                 sigaddset(&set, SIGHUP);
87                 sigaddset(&set, SIGINT);
88                 sigaddset(&set, SIGQUIT);
89                 sigaddset(&set, SIGTERM);
90                 sigprocmask (SIG_BLOCK, &set, &oset);
91             }
92             fprintf (fp, "%s: %s\n", mp->msgattrs[i], cp);
93         }
94     }
95
96     if (fp) {
97         lkfclose (fp, seqfile);
98         sigprocmask (SIG_SETMASK, &oset, &set);  /* reset signal mask */
99     } else {
100         /*
101          * If folder is not readonly, and we didn't save any
102          * public sequences, then remove that file.
103          */
104         if (!is_readonly(mp))
105             unlink (seqfile);
106     }
107
108     /*
109      * Reset folder flag, since we may be
110      * pretending that folder is readonly.
111      */
112     mp->msgflags = flags;
113 }