File: seq_save.c

package info (click to toggle)
nmh 1.0.2-9
  • links: PTS
  • area: main
  • in suites: potato
  • size: 3,172 kB
  • ctags: 4,449
  • sloc: ansic: 50,696; sh: 1,799; makefile: 1,192; awk: 74; sed: 17
file content (115 lines) | stat: -rw-r--r-- 2,921 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

/*
 * seq_save.c -- 1) synchronize sequences
 *            -- 2) save public sequences
 *
 * $Id: seq_save.c,v 1.1.1.1 1999/04/30 18:08:34 doug Exp $
 */

#include <h/mh.h>
#include <h/signals.h>


/*
 * 1.  If sequence is public and folder is readonly,
 *     then change it to be private
 * 2a. If sequence is public, then add it to the sequences file
 *     in folder (name specified by mh-sequences profile entry).
 * 2b. If sequence is private, then add it to the
 *     context file.
 */

void
seq_save (struct msgs *mp)
{
    int i;
    char flags, *cp, attr[BUFSIZ], seqfile[PATH_MAX];
    FILE *fp;
    sigset_t set, oset;

    /* sanity check - check that context has been read */
    if (defpath == NULL)
	adios (NULL, "oops, context hasn't been read yet");

    /* check if sequence information has changed */
    if (!(mp->msgflags & SEQMOD))
	return;
    mp->msgflags &= ~SEQMOD;

    fp = NULL;
    flags = mp->msgflags;	/* record folder flags */

    /*
     * If no mh-sequences file is defined, or if a mh-sequences file
     * is defined but empty (*mh_seq == '\0'), then pretend folder
     * is readonly.  This will force all sequences to be private.
     */
    if (mh_seq == NULL || *mh_seq == '\0')
	set_readonly (mp);
    else
	snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);

    for (i = 0; mp->msgattrs[i]; i++) {
	snprintf (attr, sizeof(attr), "atr-%s-%s", mp->msgattrs[i], mp->foldpath);

	/* get space separated list of sequence ranges */
	if (!(cp = seq_list(mp, mp->msgattrs[i]))) {
	    context_del (attr);			/* delete sequence from context */
	    continue;
	}

	if (is_readonly(mp) || is_seq_private(mp, i)) {
priv:
	    /*
	     * sequence is private
	     */
	    context_replace (attr, cp);		/* update sequence in context   */
	} else {
	    /*
	     * sequence is public
	     */
	    context_del (attr);			/* delete sequence from context */

	    if (!fp) {
		/*
		 * Attempt to open file for public sequences.
		 * If that fails (probably because folder is
		 * readonly), then make sequence private.
		 */
		if ((fp = fopen (seqfile, "w")) == NULL
			&& (unlink (seqfile) == -1 ||
			    (fp = fopen (seqfile, "w")) == NULL)) {
		    admonish (attr, "unable to write");
		    goto priv;
		}

		/* block a few signals */
		sigemptyset (&set);
		sigaddset(&set, SIGHUP);
		sigaddset(&set, SIGINT);
		sigaddset(&set, SIGQUIT);
		sigaddset(&set, SIGTERM);
		SIGPROCMASK (SIG_BLOCK, &set, &oset);
	    }
	    fprintf (fp, "%s: %s\n", mp->msgattrs[i], cp);
	}
    }

    if (fp) {
	fclose (fp);
	SIGPROCMASK (SIG_SETMASK, &oset, &set);  /* reset signal mask */
    } else {
	/*
	 * If folder is not readonly, and we didn't save any
	 * public sequences, then remove that file.
	 */
	if (!is_readonly(mp))
	    unlink (seqfile);
    }

    /*
     * Reset folder flag, since we may be
     * pretending that folder is readonly.
     */
    mp->msgflags = flags;
}