File: folder_read.c

package info (click to toggle)
nmh 1.0.2-9
  • links: PTS
  • area: main
  • in suites: potato
  • size: 3,172 kB
  • ctags: 4,449
  • sloc: ansic: 50,696; sh: 1,799; makefile: 1,192; awk: 74; sed: 17
file content (163 lines) | stat: -rw-r--r-- 3,978 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

/*
 * folder_read.c -- initialize folder structure and read folder
 *
 * $Id: folder_read.c,v 1.1.1.1 1999/04/30 18:08:34 doug Exp $
 */

#include <h/mh.h>

/* We allocate the `mi' array 1024 elements at a time */
#define	NUMMSGS  1024

/*
 * 1) Create the folder/message structure
 * 2) Read the directory (folder) and temporarily
 *    record the numbers of the messages we have seen.
 * 3) Then allocate the array for message attributes and
 *    set the initial flags for all messages we've seen.
 * 4) Read and initialize the sequence information.
 */

struct msgs *
folder_read (char *name)
{
    int msgnum, prefix_len, len, *mi;
    struct msgs *mp;
    struct stat st;
    struct dirent *dp;
    DIR *dd;

    name = m_mailpath (name);
    if (!(dd = opendir (name))) {
	free (name);
	return NULL;
    }

    if (stat (name, &st) == -1) {
	free (name);
	return NULL;
    }

    /* Allocate the main structure for folder information */
    if (!(mp = (struct msgs *) malloc ((size_t) sizeof(*mp))))
	adios (NULL, "unable to allocate folder storage");

    clear_folder_flags (mp);
    mp->foldpath = name;
    mp->lowmsg = 0;
    mp->hghmsg = 0;
    mp->curmsg = 0;
    mp->lowsel = 0;
    mp->hghsel = 0;
    mp->numsel = 0;
    mp->nummsg = 0;

    if (access (name, W_OK) == -1 || st.st_uid != getuid())
	set_readonly (mp);
    prefix_len = strlen(BACKUP_PREFIX);

    /*
     * Allocate a temporary place to record the
     * name of the messages in this folder.
     */
    len = NUMMSGS;
    if (!(mi = (int *) malloc ((size_t) (len * sizeof(*mi)))))
	adios (NULL, "unable to allocate storage");

    while ((dp = readdir (dd))) {
	if ((msgnum = m_atoi (dp->d_name))) {
	    /*
	     * Check if we need to allocate more
	     * temporary elements for message names.
	     */
	    if (mp->nummsg >= len) {
		len += NUMMSGS;
		if (!(mi = (int *) realloc (mi,
			(size_t) (len * sizeof(*mi))))) {
		    adios (NULL, "unable to allocate storage");
		}
	    }

	    /* Check if this is the first message we've seen */
	    if (mp->nummsg == 0) {
		mp->lowmsg = msgnum;
		mp->hghmsg = msgnum;
	    } else {
		/* Check if this is it the highest or lowest we've seen? */
		if (msgnum < mp->lowmsg)
		   mp->lowmsg = msgnum;
		if (msgnum > mp->hghmsg)
		   mp->hghmsg = msgnum;
	    }

	    /*
	     * Now increment count, and record message
	     * number in a temporary place for now.
	     */
	    mi[mp->nummsg++] = msgnum;

	} else {
	    switch (dp->d_name[0]) {
		case '.': 
		case ',': 
#ifdef MHE
		case '+': 
#endif /* MHE */
		    continue;

		default: 
		    /* skip any files beginning with backup prefix */
		    if (!strncmp (dp->d_name, BACKUP_PREFIX, prefix_len))
			continue;

		    /* skip the LINK file */
		    if (!strcmp (dp->d_name, LINK))
			continue;

		    /* indicate that there are other files in folder */
		    set_other_files (mp);
		    continue;
	    }
	}
    }

    closedir (dd);
    mp->lowoff = max (mp->lowmsg, 1);

    /* Go ahead and allocate space for 100 additional messages. */
    mp->hghoff = mp->hghmsg + 100;

    /* for testing, allocate minimal necessary space */
    /* mp->hghoff = max (mp->hghmsg, 1); */

    /*
     * Allocate space for status of each message.
     */
    if (!(mp->msgstats = malloc (MSGSTATSIZE(mp, mp->lowoff, mp->hghoff))))
	adios (NULL, "unable to allocate storage for msgstats");

    /*
     * Clear all the flag bits for all the message
     * status entries we just allocated.
     */
    for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++)
	clear_msg_flags (mp, msgnum);

    /*
     * Scan through the array of messages we've seen and
     * setup the initial flags for those messages in the
     * newly allocated mp->msgstats area.
     */
    for (msgnum = 0; msgnum < mp->nummsg; msgnum++)
	set_exists (mp, mi[msgnum]);

    free (mi);		/* We don't need this anymore    */

    /*
     * Read and initialize the sequence information.
     */
    seq_read (mp);

    return mp;
}