3d2e5497a68b45381965b3dbe66b7d524bef6666
[mmh] / 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)
26 {
27     pid_t pid;
28     int msgnum, vecp, retval = 0;
29     char buf[100], *dp, **vec;
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         if (mp->numsel > MAXARGS - 2)
45             adios (NULL, "more than %d messages for %s exec", MAXARGS - 2,
46                    rmmproc);
47         vec = (char **) calloc ((size_t) (mp->numsel + 2), sizeof(*vec));
48         if (vec == NULL)
49             adios (NULL, "unable to allocate exec vector");
50         vecp = 1;
51         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
52             if (is_selected (mp, msgnum) &&
53                 !(vec[vecp++] = strdup (m_name (msgnum))))
54                 adios (NULL, "strdup failed");
55         }
56         vec[vecp] = NULL;
57
58         fflush (stdout);
59         vec[0] = r1bindex (rmmproc, '/');
60
61         switch (pid = vfork()) {
62         case -1:
63             advise ("fork", "unable to");
64             return -1;
65
66         case 0:
67             execvp (rmmproc, vec);
68             fprintf (stderr, "unable to exec ");
69             perror (rmmproc);
70             _exit (-1);
71
72         default:
73             return (pidwait (pid, -1));
74         }
75     }
76
77     /*
78      * Either unlink or rename the SELECTED messages
79      */
80     for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
81         if (is_selected (mp, msgnum)) {
82             /* unselect message */
83             unset_selected (mp, msgnum);
84             mp->numsel--;
85
86             dp = m_name (msgnum);
87
88             if (unlink_msgs) {
89                 /* just unlink the messages */
90                 if (unlink (dp) == -1) {
91                     admonish (dp, "unable to unlink");
92                     retval = -1;
93                     continue;
94                 }
95             } else {
96                 /* or rename messages with standard prefix */
97                 strncpy (buf, m_backup (dp), sizeof(buf));
98                 if (rename (dp, buf) == -1) {
99                     admonish (buf, "unable to rename %s to", dp);
100                     retval = -1;
101                     continue;
102                 }
103             }
104
105             /* If removal was successful, decrement message count */
106             unset_exists (mp, msgnum);
107             mp->nummsg--;
108         }
109     }
110
111     /* Sanity check */
112     if (mp->numsel != 0)
113         adios (NULL, "oops, mp->numsel should be 0");
114
115     /* Mark that the sequence information has changed */
116     mp->msgflags |= SEQMOD;
117
118     return retval;
119 }