1 /* m_gmsg.c - read a folder */
19 #define NINFO (MAXFOLDER / 5) /* PLEASE be non-trivial... */
25 static int m_getatr(), m_setatr();
28 static struct info *head;
42 register struct info *rover,
48 register struct msgs *mp;
49 register struct direct *dp;
53 if ((dd = opendir (name = m_mailpath (name))) == NULL) {
57 (void) fstat (dd->dd_fd, &st);
59 mp = (struct msgs *) malloc (MSIZE (mp, 0, 0));
61 adios (NULLCP, "unable to allocate folder storage");
62 mp->lowmsg = mp->hghmsg = mp->nummsg = 0;
64 mp->lowsel = mp->hghsel = mp->numsel = 0;
67 if (st.st_uid != getuid () || access (name, 02) == NOTOK)
68 mp->msgflags |= READONLY;
74 if ((head = (struct info *)
75 malloc ((unsigned) ((len = NINFO) * sizeof *head))) == NULL)
76 adios (NULLCP, "unable to allocate info storage");
77 tail = (rover = head) + len;
79 while (dp = readdir (dd))
80 if (i = m_atoi (dp->d_name)) {
82 register int curlen = tail - head;
84 if ((tail = (struct info *) realloc ((char *) head,
85 (unsigned) ((len += NINFO) * sizeof *head)))
87 adios (NULLCP, "unable to allocate info storage");
89 rover = tail + curlen, head = tail, tail += len;
94 if (mp->lowmsg == 0 || i < mp->lowmsg)
97 rover->stats = EXISTS;
99 rover->stats &= ~DELETED;
104 switch (dp->d_name[0]) {
110 if ((i = m_atoi (dp->d_name + 1)) {
111 register struct info *l;
113 for (l = head; l < rover; l++)
115 if (!(l->stats & EXISTS))
136 if (strcmp (dp->d_name, current) == 0) {
141 if (strcmp (dp->d_name, LINK) == 0
142 || strncmp (dp->d_name, SBACKUP, j) == 0)
144 mp->msgflags |= OTHERS;
153 (void) sprintf (buffer, "%s-%s", current, name);
154 if (cp = m_find (buffer)) {
156 (void) m_delete(buffer);
160 if (mp->curmsg == 0 && cur && (fd = open (current, 0)) != NOTOK) {
161 if ((i = read (fd, buffer, sizeof buffer)) > 0) {
162 if (cp = index (buffer, '\n'))
164 if ((i = m_atoi (buffer)) > 0)
169 if (cur && !(mp->msgflags & READONLY)){ /* sneaky... */
170 (void) sprintf (buffer, "%s/%s", name, current);
171 (void) unlink (buffer);
178 mp->lowoff = mp->lowmsg;
180 mp->hghoff = mp->hghmsg + 1;/* for "new" in m_convert */
183 realloc ((char *) mp, MSIZE (mp, mp->lowoff, mp->hghoff));
185 adios (NULLCP, "unable to allocate folder storage");
187 for (i = mp->lowmsg; i <= mp->hghmsg; i++)
190 mp->msgstats = (int *)
191 calloc ((unsigned) 1, MSIZEX (mp, mp->lowmsg, mp->hghmsg));
192 if (mp->msgstats == NULL)
193 adios (NULLCP, "unable to allocate messages storage");
194 mp->msgstats = (mp->msgbase = mp->msgstats) - mp->lowoff;
195 if (mp->msgstats < 0)
196 adios (NULLCP, "m_gmsg() botch -- you lose big");
198 for (tail = head; tail < rover; tail++)
199 mp->msgstats[tail->msgno] = tail->stats;
209 register struct msgs *mp;
220 register struct node *np;
225 mp->msgattrs[0] = getcpy (current);
226 mp->msgattrs[1] = NULL;
227 mp->attrstats = 0; /* initially, all public */
230 if (mh_seq == NULL || *mh_seq == NULL)
233 (void) sprintf (field, "%s/%s", mp->foldpath, mh_seq);
234 if (fp = fopen (field, "r")) {
235 for (state = FLD;;) {
236 switch (state = m_getfld (state, name, field, sizeof field, fp)) {
239 * sequence was too big for buffer: back up
242 for (cp = &field[sizeof(field)-2]; !isspace(*cp); --cp)
244 if (i = cp - &field[sizeof(field)-2]) {
250 (void) m_setatr (mp, name, field);
254 (void) m_setatr (mp, name, field);
260 "no blank lines are permitted in %s/%s",
261 mp->foldpath, mh_seq);/* fall */
267 adios (NULLCP, "%s/%s is poorly formatted",
268 mp->foldpath, mh_seq);
276 alen = strlen ("atr-");
277 plen = strlen (mp->foldpath) + 1;
279 for (np = m_defs; np; np = np->n_next)
280 if (ssequal ("atr-", np->n_name)
281 && (j = strlen (np->n_name) - plen) > alen
282 && *(np->n_name + j) == '-'
283 && strcmp (mp->foldpath, np->n_name + j + 1) == 0) {
284 cp = getcpy (np->n_name + alen);
285 *(cp + j - alen) = NULL;
286 if ((i = m_setatr (mp, cp, np->n_field)) != NOTOK)
287 mp->attrstats |= 1 << (bits + i);/* private */
295 m_setatr(mp, name, field)
296 register struct msgs *mp;
297 register char *name, *field;
299 register int bits, slot, first, last;
302 if (strcmp (current, name) == 0) {
303 mp->curmsg = atoi(field);
307 for (slot = 0; mp->msgattrs[slot]; slot++)
308 if (strcmp(mp->msgattrs[slot], name) == 0)
314 if (mp->msgattrs[slot] == NULL) {
315 mp->msgattrs[slot] = getcpy(name);
316 mp->msgattrs[slot + 1] = NULL;
319 bits = 1 << (FFATTRSLOT + slot);
321 for (cp = field; *cp; ) {
326 for (first = 0; isdigit(*cp); ++cp)
327 first = (first * 10) + (*cp - '0');
331 /* have a range of msgs */
332 for (last = 0; isdigit(*cp); ++cp)
333 last = (last * 10) + (*cp - '0');
336 "seq %s msg range bad: first (%d) > last (%d)",
340 if (last < mp->lowmsg)
342 if (last > mp->hghmsg)
344 if (first < mp->lowmsg)
347 if (first < mp->lowmsg)
351 for ( ; first <= last; ++first)
352 if (mp->msgstats[first] & EXISTS)
353 mp->msgstats[first] |= bits;