1 /* folder_pack.c -- pack (renumber) the messages in a folder
2  *               -- into a contiguous range from 1 to n.
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  * Pack the message in a folder.
13  * Return -1 if error, else return 0.
14  */
15 
16 int
folder_pack(struct msgs ** mpp,int verbose)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 	    inform("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 		/*
53 		 * Invoke the external refile hook for each message being renamed.
54 		 * This is done before the file is renamed so that the old message
55 		 * file is around for the hook.
56 		 */
57 
58 		(void)snprintf(oldmsg, sizeof (oldmsg), "%s/%d", mp->foldpath, msgnum);
59 		(void)snprintf(newmsg, sizeof (newmsg), "%s/%d", mp->foldpath, hole);
60 		ext_hook("ref-hook", oldmsg, newmsg);
61 
62 		/* move the message file */
63 		if (rename (oldmsg, newmsg) == -1) {
64 		    advise (newmsg, "unable to rename %s to", oldmsg);
65 		    return -1;
66 		}
67 
68 		/* check if this is the current message */
69 		if (msgnum == mp->curmsg)
70 		    newcurrent = hole;
71 
72 		/* copy the attribute flags for this message */
73 		copy_msg_flags (mp, hole, msgnum);
74 
75 		if (msgnum == mp->lowsel)
76 		    mp->lowsel = hole;
77 		if (msgnum == mp->hghsel)
78 		    mp->hghsel = hole;
79 
80 		/* mark that sequence information has been modified */
81 		mp->msgflags |= SEQMOD;
82 	    }
83 	    hole++;
84 	}
85     }
86 
87     /* record the new number for the high/low message */
88     mp->lowmsg = 1;
89     mp->hghmsg = hole - 1;
90 
91     /* update the "cur" sequence */
92     if (newcurrent != 0)
93 	seq_setcur (mp, newcurrent);
94 
95     return 0;
96 }
97