]> diplodocus.org Git - nmh/blob - sbr/seq_save.c
Bring these changes over from the branch.
[nmh] / 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 /* sanity check - check that context has been read */
35 if (defpath == NULL)
36 adios (NULL, "oops, context hasn't been read yet");
37
38 /* check if sequence information has changed */
39 if (!(mp->msgflags & SEQMOD))
40 return;
41 mp->msgflags &= ~SEQMOD;
42
43 fp = NULL;
44 flags = mp->msgflags; /* record folder flags */
45
46 /*
47 * If no mh-sequences file is defined, or if a mh-sequences file
48 * is defined but empty (*mh_seq == '\0'), then pretend folder
49 * is readonly. This will force all sequences to be private.
50 */
51 if (mh_seq == NULL || *mh_seq == '\0')
52 set_readonly (mp);
53 else
54 snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
55
56 for (i = 0; mp->msgattrs[i]; i++) {
57 snprintf (attr, sizeof(attr), "atr-%s-%s", mp->msgattrs[i], mp->foldpath);
58
59 /* get space separated list of sequence ranges */
60 if (!(cp = seq_list(mp, mp->msgattrs[i]))) {
61 context_del (attr); /* delete sequence from context */
62 continue;
63 }
64
65 if (is_readonly(mp) || is_seq_private(mp, i)) {
66 priv:
67 /*
68 * sequence is private
69 */
70 context_replace (attr, cp); /* update sequence in context */
71 } else {
72 /*
73 * sequence is public
74 */
75 context_del (attr); /* delete sequence from context */
76
77 if (!fp) {
78 /*
79 * Attempt to open file for public sequences.
80 * If that fails (probably because folder is
81 * readonly), then make sequence private.
82 */
83 if ((fp = fopen (seqfile, "w")) == NULL
84 && (unlink (seqfile) == -1 ||
85 (fp = fopen (seqfile, "w")) == NULL)) {
86 admonish (attr, "unable to write");
87 goto priv;
88 }
89
90 /* block a few signals */
91 sigemptyset (&set);
92 sigaddset(&set, SIGHUP);
93 sigaddset(&set, SIGINT);
94 sigaddset(&set, SIGQUIT);
95 sigaddset(&set, SIGTERM);
96 SIGPROCMASK (SIG_BLOCK, &set, &oset);
97 }
98 fprintf (fp, "%s: %s\n", mp->msgattrs[i], cp);
99 }
100 }
101
102 if (fp) {
103 fclose (fp);
104 SIGPROCMASK (SIG_SETMASK, &oset, &set); /* reset signal mask */
105 } else {
106 /*
107 * If folder is not readonly, and we didn't save any
108 * public sequences, then remove that file.
109 */
110 if (!is_readonly(mp))
111 unlink (seqfile);
112 }
113
114 /*
115 * Reset folder flag, since we may be
116 * pretending that folder is readonly.
117 */
118 mp->msgflags = flags;
119 }