Implement the following changes:
[mmh] / 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;
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         if (mp->numsel > MAXARGS - 2)
44             adios (NULL, "more than %d messages for %s exec", MAXARGS - 2,
45                    rmmproc);
46         vec = (char **) calloc ((size_t) (mp->numsel + 2), sizeof(*vec));
47         if (vec == NULL)
48             adios (NULL, "unable to allocate exec vector");
49         vecp = 1;
50         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
51             if (is_selected (mp, msgnum) &&
52                 !(vec[vecp++] = strdup (m_name (msgnum))))
53                 adios (NULL, "strdup failed");
54         }
55         vec[vecp] = NULL;
56
57         fflush (stdout);
58         vec[0] = r1bindex (rmmproc, '/');
59
60         switch (pid = vfork()) {
61         case -1:
62             advise ("fork", "unable to");
63             return -1;
64
65         case 0:
66             execvp (rmmproc, vec);
67             fprintf (stderr, "unable to exec ");
68             perror (rmmproc);
69             _exit (-1);
70
71         default:
72             return (pidwait (pid, -1));
73         }
74     }
75
76     /*
77      * Either unlink or rename the SELECTED messages
78      */
79     for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
80         if (is_selected (mp, msgnum)) {
81             /* unselect message */
82             unset_selected (mp, msgnum);
83             mp->numsel--;
84
85             /*
86              *  Run the external hook on the message if one was specified in the context.
87              *  All we have is the message number; we have changed to the directory
88              *  containing the message.  So, we need to extract that directory to form
89              *  the complete path.  Note that the caller knows the directory, but has
90              *  no way of passing that to us.
91              */
92
93             if (!nohook) {
94                     (void)snprintf(msgpath, sizeof (msgpath), "%s/%d", mp->foldpath, msgnum);
95                     (void)ext_hook("del-hook", msgpath, (char *)0);
96                 }
97
98             dp = m_name (msgnum);
99
100             if (unlink_msgs) {
101                 /* just unlink the messages */
102                 if (unlink (dp) == -1) {
103                     admonish (dp, "unable to unlink");
104                     retval = -1;
105                     continue;
106                 }
107             } else {
108                 /* or rename messages with standard prefix */
109                 strncpy (buf, m_backup (dp), sizeof(buf));
110                 if (rename (dp, buf) == -1) {
111                     admonish (buf, "unable to rename %s to", dp);
112                     retval = -1;
113                     continue;
114                 }
115             }
116
117             /* If removal was successful, decrement message count */
118             unset_exists (mp, msgnum);
119             mp->nummsg--;
120         }
121     }
122
123     /* Sanity check */
124     if (mp->numsel != 0)
125         adios (NULL, "oops, mp->numsel should be 0");
126
127     /* Mark that the sequence information has changed */
128     mp->msgflags |= SEQMOD;
129
130     return retval;
131 }