]> diplodocus.org Git - nmh/blob - sbr/folder_delmsgs.c
a33adf603eda621465c3ab490b6cb8a89b52e816
[nmh] / sbr / folder_delmsgs.c
1 /* folder_delmsgs.c -- "remove" SELECTED messages from a folder
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include "h/mh.h"
9 #include "folder_delmsgs.h"
10 #include "context_save.h"
11 #include "arglist.h"
12 #include "error.h"
13 #include "h/utils.h"
14 #include "m_mktemp.h"
15
16 /*
17 * 1) If we are using an external rmmproc, then exec it.
18 * 2) Else if unlink_msgs is non-zero, then unlink the
19 * SELECTED messages.
20 * 3) Else rename SELECTED messages by prefixing name
21 * with a standard prefix.
22 *
23 * If there is an error, return -1, else return 0.
24 */
25
26 int
27 folder_delmsgs (struct msgs *mp, int unlink_msgs, int nohook)
28 {
29 pid_t pid;
30 int msgnum, vecp, retval = 0;
31 char buf[100], *dp, **vec, *prog;
32 char msgpath[BUFSIZ];
33
34 /*
35 * If "rmmproc" is defined, exec it to remove messages.
36 */
37 if (rmmproc) {
38 /* Unset the EXISTS flag for each message to be removed */
39 for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
40 if (is_selected (mp, msgnum))
41 unset_exists (mp, msgnum);
42 }
43
44 /* Mark that the sequence information has changed */
45 mp->msgflags |= SEQMOD;
46
47 /*
48 * Write out the sequence and context files; this will release
49 * any locks before the rmmproc is called.
50 */
51
52 seq_save (mp);
53 context_save ();
54
55 vec = argsplit(rmmproc, &prog, &vecp);
56
57 /*
58 * argsplit allocates a MAXARGS vector by default, If we need
59 * something bigger, allocate it ourselves
60 */
61
62 if (mp->numsel + vecp + 1 > MAXARGS)
63 vec = mh_xrealloc(vec, (mp->numsel + vecp + 1) * sizeof *vec);
64 for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
65 if (is_selected (mp, msgnum) &&
66 !(vec[vecp++] = strdup (m_name (msgnum))))
67 die("strdup failed");
68 }
69 vec[vecp] = NULL;
70
71 fflush (stdout);
72
73 switch (pid = fork()) {
74 case -1:
75 advise ("fork", "unable to");
76 return -1;
77
78 case 0:
79 execvp (prog, vec);
80 fprintf (stderr, "unable to exec ");
81 perror (rmmproc);
82 _exit(1);
83
84 default:
85 arglist_free(prog, vec);
86 return pidwait(pid, -1);
87 }
88 }
89
90 /*
91 * Either unlink or rename the SELECTED messages
92 */
93 for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
94 if (is_selected (mp, msgnum)) {
95 /* unselect message */
96 unset_selected (mp, msgnum);
97 mp->numsel--;
98
99 /*
100 * Run the external hook on the message if one was specified in the context.
101 * All we have is the message number; we have changed to the directory
102 * containing the message. So, we need to extract that directory to form
103 * the complete path. Note that the caller knows the directory, but has
104 * no way of passing that to us.
105 */
106
107 if (!nohook) {
108 (void)snprintf(msgpath, sizeof (msgpath), "%s/%d", mp->foldpath, msgnum);
109 (void)ext_hook("del-hook", msgpath, NULL);
110 }
111
112 dp = m_name (msgnum);
113
114 if (unlink_msgs) {
115 /* just unlink the messages */
116 if (m_unlink (dp) == -1) {
117 admonish (dp, "unable to unlink");
118 retval = -1;
119 continue;
120 }
121 } else {
122 /* or rename messages with standard prefix */
123 strncpy (buf, m_backup (dp), sizeof(buf));
124 if (rename (dp, buf) == -1) {
125 admonish (buf, "unable to rename %s to", dp);
126 retval = -1;
127 continue;
128 }
129 }
130
131 /* If removal was successful, decrement message count */
132 unset_exists (mp, msgnum);
133 mp->nummsg--;
134 }
135 }
136
137 /* Sanity check */
138 if (mp->numsel != 0)
139 die("oops, mp->numsel should be 0");
140
141 /* Mark that the sequence information has changed */
142 mp->msgflags |= SEQMOD;
143
144 /*
145 * Write out sequence and context files
146 */
147
148 seq_save (mp);
149 context_save ();
150
151 return retval;
152 }