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