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