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