]> diplodocus.org Git - nmh/blob - sbr/seq_save.c
* I had alphabetized the --configure options in the --help output
[nmh] / sbr / seq_save.c
1
2 /*
3 * seq_save.c -- 1) synchronize sequences
4 * -- 2) save public sequences
5 *
6 * $Id$
7 */
8
9 #include <h/mh.h>
10 #include <h/signals.h>
11
12
13 /*
14 * 1. If sequence is public and folder is readonly,
15 * then change it to be private
16 * 2a. If sequence is public, then add it to the sequences file
17 * in folder (name specified by mh-sequences profile entry).
18 * 2b. If sequence is private, then add it to the
19 * context file.
20 */
21
22 void
23 seq_save (struct msgs *mp)
24 {
25 int i;
26 char flags, *cp, attr[BUFSIZ], seqfile[PATH_MAX];
27 FILE *fp;
28 sigset_t set, oset;
29
30 /* sanity check - check that context has been read */
31 if (defpath == NULL)
32 adios (NULL, "oops, context hasn't been read yet");
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 = fopen (seqfile, "w")) == NULL
80 && (unlink (seqfile) == -1 ||
81 (fp = fopen (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 fclose (fp);
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 }