mhl and mhbuild ignore to long lines
[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 <unistd.h>
10 #include <h/mh.h>
11 #include <h/utils.h>
12 #include <dirent.h>
13 #include <sys/stat.h>
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 static int others;
25
26 static int
27 msgnumcmp(const struct dirent **d1, const struct dirent **d2)
28 {
29         size_t l1, l2;
30
31         l1 = strlen((*d1)->d_name);
32         l2 = strlen((*d2)->d_name);
33         if (l1 < l2) {
34                 return -1;
35         }
36         if (l1 > l2) {
37                 return 1;
38         }
39         return strcmp((*d1)->d_name, (*d2)->d_name);
40 }
41
42 static int
43 msgfilter(const struct dirent *e)
44 {
45         int i;
46         /* For compatibility with nmh, ignore rmm backup files. */
47         if (e->d_name[0] == '.' || e->d_name[0] == ',' || e->d_name[0] == '#') {
48                 return 0;
49         }
50         for (i = 0; e->d_name[i]; i++) {
51                 if ((i == 0 && e->d_name[i] == '0') || e->d_name[i] < '0' || e->d_name[i] > '9') {
52                         others = 1;
53                         return 0;
54                 }
55         }
56         return 1;
57 }
58
59 struct msgs *
60 folder_read(char *name)
61 {
62         int i;
63         struct msgs *mp;
64         struct stat st;
65         struct dirent **dp;
66
67         others = 0;
68         name = mh_xstrdup(toabsdir(name));
69
70         if (stat(name, &st) == -1) {
71                 mh_free0(&name);
72                 return NULL;
73         }
74
75         /* Allocate the main structure for folder information */
76         mp = mh_xcalloc(1, sizeof(*mp));
77
78         mp->foldpath = name;
79
80         if (access(name, W_OK) == -1)
81                 set_readonly(mp);
82
83         mp->nummsg = scandir(name, &dp, msgfilter, msgnumcmp);
84
85         if (others)
86                 set_other_files(mp);
87
88         if (mp->nummsg < 0) {
89                 mh_free0(&name);
90                 mh_free0(&mp);
91                 return NULL;
92         }
93         if (mp->nummsg > 0) {
94                 mp->lowmsg = m_atoi(dp[0]->d_name);
95                 mp->hghmsg = m_atoi(dp[mp->nummsg-1]->d_name);
96         }
97         mp->lowoff = max(mp->lowmsg, 1);
98         mp->hghoff = mp->hghmsg + 100;
99         mp->msgstats = mh_xcalloc(MSGSTATSIZE(mp, mp->lowoff, mp->hghoff), 1);
100         for (i = 0; i < mp->nummsg; i++) {
101                 set_exists(mp, m_atoi(dp[i]->d_name));
102                 mh_free0(dp + i);
103         }
104         mh_free0(&dp);
105
106         /*
107         ** Read and initialize the sequence information.
108         */
109         seq_read(mp);
110
111         return mp;
112 }