05365a86a3a3b29a2a9c250f5a908c308ae7c5e1
[mmh] / sbr / folder_pack.c
1
2 /*
3  * folder_pack.c -- pack (renumber) the messages in a folder
4  *               -- into a contiguous range from 1 to n.
5  *
6  * $Id$
7  */
8
9 #include <h/mh.h>
10
11 /*
12  * Pack the message in a folder.
13  * Return -1 if error, else return 0.
14  */
15
16 int
17 folder_pack (struct msgs **mpp, int verbose)
18 {
19     int hole, msgnum, newcurrent = 0;
20     char newmsg[BUFSIZ], oldmsg[BUFSIZ];
21     struct msgs *mp;
22
23     mp = *mpp;
24
25     /*
26      * Just return if folder is empty.
27      */
28     if (mp->nummsg == 0)
29         return 0;
30
31     /*
32      * Make sure we have message status space allocated
33      * for all numbers from 1 to current high message.
34      */
35     if (mp->lowoff > 1) {
36         if ((mp = folder_realloc (mp, 1, mp->hghmsg)))
37             *mpp = mp;
38         else {
39             advise (NULL, "unable to allocate folder storage");
40             return -1;
41         }
42     }
43
44     for (msgnum = mp->lowmsg, hole = 1; msgnum <= mp->hghmsg; msgnum++) {
45         if (does_exist (mp, msgnum)) {
46             if (msgnum != hole) {
47                 strncpy (newmsg, m_name (hole), sizeof(newmsg));
48                 strncpy (oldmsg, m_name (msgnum), sizeof(oldmsg));
49                 if (verbose)
50                     printf ("message %s becomes %s\n", oldmsg, newmsg);
51
52                 /* move the message file */
53                 if (rename (oldmsg, newmsg) == -1) {
54                     advise (newmsg, "unable to rename %s to", oldmsg);
55                     return -1;
56                 }
57
58                 /* check if this is the current message */
59                 if (msgnum == mp->curmsg)
60                     newcurrent = hole;
61
62                 /* copy the attribute flags for this message */
63                 copy_msg_flags (mp, hole, msgnum);
64
65                 if (msgnum == mp->lowsel)
66                     mp->lowsel = hole;
67                 if (msgnum == mp->hghsel)
68                     mp->hghsel = hole;
69
70                 /* mark that sequence information has been modified */
71                 mp->msgflags |= SEQMOD;
72             }
73             hole++;
74         }
75     }
76
77     /* record the new number for the high/low message */
78     mp->lowmsg = 1;
79     mp->hghmsg = hole - 1;
80
81     /* update the "cur" sequence */
82     if (newcurrent != 0)
83         seq_setcur (mp, newcurrent);
84
85     return 0;
86 }