e5374b5d601b9a29e98f1b83e0e546cb485f7d30
[mmh] / sbr / folder_delmsgs.c
1
2 /*
3  * folder_delmsgs.c -- "remove" SELECTED messages from a folder
4  *
5  * $Id$
6  */
7
8 #include <h/mh.h>
9
10 /*
11  * 1) If we are using an external rmmproc, then exec it.
12  * 2) Else if unlink_msgs is non-zero, then unlink the
13  *    SELECTED messages.
14  * 3) Else rename SELECTED messages by prefixing name
15  *    with a standard prefix.
16  *
17  * If there is an error, return -1, else return 0.
18  */
19
20 int
21 folder_delmsgs (struct msgs *mp, int unlink_msgs)
22 {
23     pid_t pid;
24     int msgnum, vecp, retval = 0;
25     char buf[100], *dp, **vec;
26
27     /*
28      * If "rmmproc" is defined, exec it to remove messages.
29      */
30     if (rmmproc) {
31         /* Unset the EXISTS flag for each message to be removed */
32         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
33             if (is_selected (mp, msgnum))
34                 unset_exists (mp, msgnum);
35         }
36
37         /* Mark that the sequence information has changed */
38         mp->msgflags |= SEQMOD;
39
40         if (mp->numsel > MAXARGS - 2)
41             adios (NULL, "more than %d messages for %s exec", MAXARGS - 2,
42                    rmmproc);
43         vec = (char **) calloc ((size_t) (mp->numsel + 2), sizeof(*vec));
44         if (vec == NULL)
45             adios (NULL, "unable to allocate exec vector");
46         vecp = 1;
47         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
48             if (is_selected (mp, msgnum) &&
49                 !(vec[vecp++] = strdup (m_name (msgnum))))
50                 adios (NULL, "strdup failed");
51         }
52         vec[vecp] = NULL;
53
54         fflush (stdout);
55         vec[0] = r1bindex (rmmproc, '/');
56
57         switch (pid = vfork()) {
58         case -1:
59             advise ("fork", "unable to");
60             return -1;
61
62         case 0:
63             execvp (rmmproc, vec);
64             fprintf (stderr, "unable to exec ");
65             perror (rmmproc);
66             _exit (-1);
67
68         default:
69             return (pidwait (pid, -1));
70         }
71     }
72
73     /*
74      * Either unlink or rename the SELECTED messages
75      */
76     for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
77         if (is_selected (mp, msgnum)) {
78             /* unselect message */
79             unset_selected (mp, msgnum);
80             mp->numsel--;
81
82             dp = m_name (msgnum);
83
84             if (unlink_msgs) {
85                 /* just unlink the messages */
86                 if (unlink (dp) == -1) {
87                     admonish (dp, "unable to unlink");
88                     retval = -1;
89                     continue;
90                 }
91             } else {
92                 /* or rename messages with standard prefix */
93                 strncpy (buf, m_backup (dp), sizeof(buf));
94                 if (rename (dp, buf) == -1) {
95                     admonish (buf, "unable to rename %s to", dp);
96                     retval = -1;
97                     continue;
98                 }
99             }
100
101             /* If removal was successful, decrement message count */
102             unset_exists (mp, msgnum);
103             mp->nummsg--;
104         }
105     }
106
107     /* Sanity check */
108     if (mp->numsel != 0)
109         adios (NULL, "oops, mp->numsel should be 0");
110
111     /* Mark that the sequence information has changed */
112     mp->msgflags |= SEQMOD;
113
114     return retval;
115 }