]> diplodocus.org Git - nmh/blob - sbr/folder_read.c
h/prototypes.h: Remove scan_reset_m_getfld_state() prototype.
[nmh] / sbr / folder_read.c
1 /* folder_read.c -- initialize folder structure and read folder
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/utils.h>
10
11 /* We allocate the `mi' array 1024 elements at a time */
12 #define NUMMSGS 1024
13
14 /*
15 * 1) Create the folder/message structure
16 * 2) Read the directory (folder) and temporarily
17 * record the numbers of the messages we have seen.
18 * 3) Then allocate the array for message attributes and
19 * set the initial flags for all messages we've seen.
20 * 4) Read and initialize the sequence information.
21 */
22
23 struct msgs *
24 folder_read (char *name, int lockflag)
25 {
26 int msgnum, len, *mi;
27 struct msgs *mp;
28 struct dirent *dp;
29 DIR *dd;
30 struct bvector *v;
31 size_t i;
32
33 name = m_mailpath (name);
34 if (!(dd = opendir (name))) {
35 free (name);
36 return NULL;
37 }
38
39 /* Allocate the main structure for folder information */
40 NEW(mp);
41 clear_folder_flags (mp);
42 mp->foldpath = name;
43 mp->lowmsg = 0;
44 mp->hghmsg = 0;
45 mp->curmsg = 0;
46 mp->lowsel = 0;
47 mp->hghsel = 0;
48 mp->numsel = 0;
49 mp->nummsg = 0;
50 mp->seqhandle = NULL;
51 mp->seqname = NULL;
52
53 if (access (name, W_OK) == -1)
54 set_readonly (mp);
55
56 /*
57 * Allocate a temporary place to record the
58 * name of the messages in this folder.
59 */
60 len = NUMMSGS;
61 mi = (int *) mh_xmalloc ((size_t) (len * sizeof(*mi)));
62
63 while ((dp = readdir (dd))) {
64 if ((msgnum = m_atoi (dp->d_name)) && msgnum > 0) {
65 /*
66 * Check if we need to allocate more
67 * temporary elements for message names.
68 */
69 if (mp->nummsg >= len) {
70 len += NUMMSGS;
71 mi = (int *) mh_xrealloc (mi, (size_t) (len * sizeof(*mi)));
72 }
73
74 /* Check if this is the first message we've seen */
75 if (mp->nummsg == 0) {
76 mp->lowmsg = msgnum;
77 mp->hghmsg = msgnum;
78 } else {
79 /* Check if this is it the highest or lowest we've seen? */
80 if (msgnum < mp->lowmsg)
81 mp->lowmsg = msgnum;
82 if (msgnum > mp->hghmsg)
83 mp->hghmsg = msgnum;
84 }
85
86 /*
87 * Now increment count, and record message
88 * number in a temporary place for now.
89 */
90 mi[mp->nummsg++] = msgnum;
91
92 } else {
93 switch (dp->d_name[0]) {
94 case '.':
95 case ',':
96 continue;
97
98 default:
99 /* skip any files beginning with backup prefix */
100 if (has_prefix(dp->d_name, BACKUP_PREFIX))
101 continue;
102
103 /* skip the LINK file */
104 if (!strcmp (dp->d_name, LINK))
105 continue;
106
107 /* indicate that there are other files in folder */
108 set_other_files (mp);
109 continue;
110 }
111 }
112 }
113
114 closedir (dd);
115 mp->lowoff = max (mp->lowmsg, 1);
116
117 /* Go ahead and allocate space for 100 additional messages. */
118 mp->hghoff = mp->hghmsg + 100;
119
120 /* for testing, allocate minimal necessary space */
121 /* mp->hghoff = max (mp->hghmsg, 1); */
122
123 /*
124 * If for some reason hghoff < lowoff (like we got an integer overflow)
125 * the complain about this now.
126 */
127
128 if (mp->hghoff < mp->lowoff) {
129 adios(NULL, "Internal failure: high message limit < low message "
130 "limit; possible overflow?");
131 }
132
133 /*
134 * Allocate space for status of each message.
135 */
136 mp->num_msgstats = MSGSTATNUM (mp->lowoff, mp->hghoff);
137 mp->msgstats = mh_xmalloc (MSGSTATSIZE(mp));
138 for (i = 0, v = mp->msgstats; i < mp->num_msgstats; ++i, ++v) {
139 bvector_init(v);
140 }
141
142 mp->msgattrs = svector_create (0);
143
144 /*
145 * Scan through the array of messages we've seen and
146 * setup the initial flags for those messages in the
147 * newly allocated mp->msgstats area.
148 */
149 for (msgnum = 0; msgnum < mp->nummsg; msgnum++)
150 set_exists (mp, mi[msgnum]);
151
152 free (mi); /* We don't need this anymore */
153
154 /*
155 * Read and initialize the sequence information.
156 */
157 if (seq_read (mp, lockflag) == NOTOK) {
158 char seqfile[PATH_MAX];
159
160 /* Failed to lock sequence file. */
161 snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
162 advise (seqfile, "failed to lock");
163
164 return NULL;
165 }
166
167 return mp;
168 }