1 | |
---|
2 | /* |
---|
3 | * seq_save.c -- 1) synchronize sequences |
---|
4 | * -- 2) save public sequences |
---|
5 | * |
---|
6 | * $Id: seq_save.c,v 1.1.1.1 1999-02-07 18:14:10 danw Exp $ |
---|
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 | } |
---|