2e321b048d10788619f3f6fb5550c2b8ea473996
[mmh] / sbr / folder_pack.c
1 /*
2  * folder_pack.c -- pack (renumber) the messages in a folder
3  *               -- into a contiguous range from 1 to n.
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  * Pack the message in a folder.
14  * Return -1 if error, else return 0.
15  */
16
17 int
18 folder_pack (struct msgs **mpp, int verbose)
19 {
20         int hole, msgnum, newcurrent = 0;
21         char newmsg[BUFSIZ], oldmsg[BUFSIZ];
22         struct msgs *mp;
23
24         mp = *mpp;
25
26         /*
27          * Just return if folder is empty.
28          */
29         if (mp->nummsg == 0)
30                 return 0;
31
32         /*
33          * Make sure we have message status space allocated
34          * for all numbers from 1 to current high message.
35          */
36         if (mp->lowoff > 1) {
37                 if ((mp = folder_realloc (mp, 1, mp->hghmsg)))
38                         *mpp = mp;
39                 else {
40                         advise (NULL, "unable to allocate folder storage");
41                         return -1;
42                 }
43         }
44
45         for (msgnum = mp->lowmsg, hole = 1; msgnum <= mp->hghmsg; msgnum++) {
46                 if (does_exist (mp, msgnum)) {
47                         if (msgnum != hole) {
48                                 strncpy (newmsg, m_name (hole), sizeof(newmsg));
49                                 strncpy (oldmsg, m_name (msgnum), sizeof(oldmsg));
50                                 if (verbose)
51                                         printf ("message %s becomes %s\n", oldmsg, newmsg);
52
53                                 /*
54                                  * Invoke the external refile hook for each message being renamed.
55                                  * This is done before the file is renamed so that the old message
56                                  * file is around for the hook.
57                                  */
58
59                                 (void)snprintf(oldmsg, sizeof (oldmsg), "%s/%d", mp->foldpath, msgnum);
60                                 (void)snprintf(newmsg, sizeof (newmsg), "%s/%d", mp->foldpath, hole);
61                                 ext_hook("ref-hook", oldmsg, newmsg);
62
63                                 /* move the message file */
64                                 if (rename (oldmsg, newmsg) == -1) {
65                                         advise (newmsg, "unable to rename %s to", oldmsg);
66                                         return -1;
67                                 }
68
69                                 /* check if this is the current message */
70                                 if (msgnum == mp->curmsg)
71                                         newcurrent = hole;
72
73                                 /* copy the attribute flags for this message */
74                                 copy_msg_flags (mp, hole, msgnum);
75
76                                 if (msgnum == mp->lowsel)
77                                         mp->lowsel = hole;
78                                 if (msgnum == mp->hghsel)
79                                         mp->hghsel = hole;
80
81                                 /* mark that sequence information has been modified */
82                                 mp->msgflags |= SEQMOD;
83                         }
84                         hole++;
85                 }
86         }
87
88         /* record the new number for the high/low message */
89         mp->lowmsg = 1;
90         mp->hghmsg = hole - 1;
91
92         /* update the "cur" sequence */
93         if (newcurrent != 0)
94                 seq_setcur (mp, newcurrent);
95
96         return 0;
97 }