Removed the altmsglink (named `@') and env var `$editalt' for repl and dist.
[mmh] / sbr / folder_read.c
1 /*
2 ** folder_read.c -- initialize folder structure and read 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 #include <h/utils.h>
11
12 /* We allocate the `mi' array 1024 elements at a time */
13 #define NUMMSGS  1024
14
15 /*
16 ** 1) Create the folder/message structure
17 ** 2) Read the directory (folder) and temporarily
18 **    record the numbers of the messages we have seen.
19 ** 3) Then allocate the array for message attributes and
20 **    set the initial flags for all messages we've seen.
21 ** 4) Read and initialize the sequence information.
22 */
23
24 struct msgs *
25 folder_read(char *name)
26 {
27         int msgnum, prefix_len, len, *mi;
28         struct msgs *mp;
29         struct stat st;
30         struct dirent *dp;
31         DIR *dd;
32
33         name = getcpy(toabsdir(name));
34         if (!(dd = opendir(name))) {
35                 free(name);
36                 return NULL;
37         }
38
39         if (stat(name, &st) == -1) {
40                 free(name);
41                 closedir(dd);
42                 return NULL;
43         }
44
45         /* Allocate the main structure for folder information */
46         mp = (struct msgs *) mh_xmalloc((size_t) sizeof(*mp));
47
48         clear_folder_flags(mp);
49         mp->foldpath = name;
50         mp->lowmsg = 0;
51         mp->hghmsg = 0;
52         mp->curmsg = 0;
53         mp->lowsel = 0;
54         mp->hghsel = 0;
55         mp->numsel = 0;
56         mp->nummsg = 0;
57
58         if (access(name, W_OK) == -1)
59                 set_readonly(mp);
60         prefix_len = strlen(backup_prefix);
61
62         /*
63         ** Allocate a temporary place to record the
64         ** name of the messages in this folder.
65         */
66         len = NUMMSGS;
67         mi = (int *) mh_xmalloc((size_t) (len * sizeof(*mi)));
68
69         while ((dp = readdir(dd))) {
70                 if ((msgnum = m_atoi(dp->d_name)) && msgnum > 0) {
71                         /*
72                         ** Check if we need to allocate more
73                         ** temporary elements for message names.
74                         */
75                         if (mp->nummsg >= len) {
76                                 len += NUMMSGS;
77                                 mi = (int *) mh_xrealloc(mi, (size_t) (len * sizeof(*mi)));
78                         }
79
80                         /* Check if this is the first message we've seen */
81                         if (mp->nummsg == 0) {
82                                 mp->lowmsg = msgnum;
83                                 mp->hghmsg = msgnum;
84                         } else {
85                                 /*
86                                 ** Check if this is it the highest or
87                                 ** lowest we've seen?
88                                 */
89                                 if (msgnum < mp->lowmsg)
90                                    mp->lowmsg = msgnum;
91                                 if (msgnum > mp->hghmsg)
92                                    mp->hghmsg = msgnum;
93                         }
94
95                         /*
96                         ** Now increment count, and record message
97                         ** number in a temporary place for now.
98                         */
99                         mi[mp->nummsg++] = msgnum;
100
101                 } else {
102                         switch (dp->d_name[0]) {
103                         case '.':
104                         case ',':
105                                 continue;
106
107                         default:
108                                 /*
109                                 ** skip any files beginning with
110                                 ** backup prefix
111                                 */
112                                 if (strncmp(dp->d_name, backup_prefix,
113                                                 prefix_len)==0)
114                                         continue;
115
116                                 /*
117                                 ** indicate that there are other
118                                 ** files in folder
119                                 */
120                                 set_other_files(mp);
121                                 continue;
122                         }
123                 }
124         }
125
126         closedir(dd);
127         mp->lowoff = max(mp->lowmsg, 1);
128
129         /* Go ahead and allocate space for 100 additional messages. */
130         mp->hghoff = mp->hghmsg + 100;
131
132         /* for testing, allocate minimal necessary space */
133         /* mp->hghoff = max(mp->hghmsg, 1); */
134
135         /* Allocate space for status of each message. */
136
137         mp->msgstats = mh_xmalloc(MSGSTATSIZE(mp, mp->lowoff, mp->hghoff));
138
139         /*
140         ** Clear all the flag bits for all the message
141         ** status entries we just allocated.
142         ** TODO: use memset() ?
143         */
144         for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++)
145                 clear_msg_flags(mp, msgnum);
146
147         /*
148         ** Scan through the array of messages we've seen and
149         ** setup the initial flags for those messages in the
150         ** newly allocated mp->msgstats area.
151         */
152         for (msgnum = 0; msgnum < mp->nummsg; msgnum++)
153                 set_exists(mp, mi[msgnum]);
154
155         free(mi);  /* We don't need this anymore */
156
157         /*
158         ** Read and initialize the sequence information.
159         */
160         seq_read(mp);
161
162         return mp;
163 }