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