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