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