Initial dockapps git repo
[dockapps.git] / wmbiff-0.4.27 / wmbiff / mboxClient.c
blobfebff7ff88fded5d4619fa65f3592de3efa87735
1 /* $Id: mboxClient.c,v 1.17 2004/03/28 00:28:58 bluehal Exp $ */
2 /* Author: Yong-iL Joh <tolkien@mizi.com>
3 Modified: Jorge GarcĂ­a <Jorge.Garcia@uv.es>
4 Rob Funk <rfunk@funknet.net>
5 Neil Spring <nspring@cs.washington.edu>
6 *
7 * MBOX checker.
9 * Last Updated : $Date: 2004/03/28 00:28:58 $
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif
17 #include "Client.h"
18 #include <sys/stat.h>
19 #include <errno.h>
20 #include <utime.h>
21 #ifdef USE_DMALLOC
22 #include <dmalloc.h>
23 #endif
25 #define PCM (pc->u).mbox
26 #define FROM_STR "From "
27 #define STATUS_STR "Status: "
29 FILE *openMailbox(Pop3 pc, const char *mbox_filename)
31 FILE *mailbox;
33 if ((mailbox = fopen(mbox_filename, "r")) == NULL) {
34 DM(pc, DEBUG_ERROR, "Error opening mailbox '%s': %s\n",
35 mbox_filename, strerror(errno));
36 pc->TotalMsgs = -1;
37 pc->UnreadMsgs = -1;
39 return (mailbox);
42 /* count the messages in a mailbox */
43 static void countMessages(Pop3 pc, const char *mbox_filename)
45 FILE *F;
46 char buf[BUF_SIZE];
47 int is_header = 0;
48 int next_from_is_start_of_header = 1;
49 int count_from = 0, count_status = 0;
50 int len_from = strlen(FROM_STR), len_status = strlen(STATUS_STR);
52 F = openMailbox(pc, mbox_filename);
53 if (F == NULL)
54 return;
56 /* count message */
57 while (fgets(buf, BUF_SIZE, F)) {
58 if (buf[0] == '\n') {
59 /* a newline by itself terminates the header */
60 if (is_header)
61 is_header = 0;
62 else
63 next_from_is_start_of_header = 1;
64 } else if (!strncmp(buf, FROM_STR, len_from)) {
65 /* A line starting with "From" is the beginning of a new header.
66 "From" in the text of the mail should get escaped by the MDA.
67 If your MDA doesn't do that, it is broken.
69 if (next_from_is_start_of_header)
70 is_header = 1;
71 if (is_header)
72 count_from++;
73 } else {
74 next_from_is_start_of_header = 0;
75 if (is_header && !strncmp(buf, STATUS_STR, len_status)
76 && strrchr(buf, 'R')) {
77 count_status++;
82 DM(pc, DEBUG_INFO, "from: %d status: %d\n", count_from, count_status);
83 pc->TotalMsgs = count_from;
84 pc->UnreadMsgs = count_from - count_status;
85 fclose(F);
88 /* check file status; hold on to file information used
89 to restore access time */
90 int
91 fileHasChanged(const char *mbox_filename, time_t * atime,
92 time_t * mtime, off_t * size)
94 struct stat st;
96 /* mbox file */
97 if (stat(mbox_filename, &st)) {
98 DMA(DEBUG_ERROR, "Can't stat '%s': %s\n",
99 mbox_filename, strerror(errno));
100 } else if (st.st_mtime != *mtime || st.st_size != *size) {
101 /* file was changed OR initially read */
102 DMA(DEBUG_INFO, " %s was changed,"
103 " mTIME: %lu -> %lu; SIZE: %lu -> %lu\n",
104 mbox_filename, *mtime, st.st_mtime,
105 (unsigned long) *size, (unsigned long) st.st_size);
107 *atime = st.st_atime;
108 *mtime = st.st_mtime;
109 *size = st.st_size;
110 return 1;
112 return 0;
115 int mboxCheckHistory(Pop3 pc)
117 char *mbox_filename = backtickExpand(pc, pc->path);
118 struct utimbuf ut;
120 DM(pc, DEBUG_INFO, ">Mailbox: '%s'\n", mbox_filename);
122 if (fileHasChanged(mbox_filename, &ut.actime, &PCM.mtime, &PCM.size)
123 || pc->OldMsgs < 0) {
125 countMessages(pc, mbox_filename);
127 /* Reset atime for (at least) MUTT to work */
128 /* ut.actime is set above */
129 ut.modtime = PCM.mtime;
130 utime(mbox_filename, &ut);
132 free(mbox_filename);
133 return 0;
136 int mboxCreate(Pop3 pc, const char *str)
138 /* MBOX format: mbox:fullpathname */
140 pc->TotalMsgs = 0;
141 pc->UnreadMsgs = 0;
142 pc->OldMsgs = -1;
143 pc->OldUnreadMsgs = -1;
144 pc->checkMail = mboxCheckHistory;
146 /* default boxes are mbox... cut mbox: if it exists */
147 if (!strncasecmp(pc->path, "mbox:", 5)) {
148 if (strlen(str + 5) + 1 > BUF_BIG) {
149 DM(pc, DEBUG_ERROR, "mbox '%s' is too long.\n", str + 5);
150 memset(pc->path, 0, BUF_BIG);
151 } else {
152 strncpy(pc->path, str + 5, BUF_BIG - 1); /* cut off ``mbox:'' */
156 DM(pc, DEBUG_INFO, "mbox: str = '%s'\n", str);
157 DM(pc, DEBUG_INFO, "mbox: path= '%s'\n", pc->path);
159 return 0;
162 /* vim:set ts=4: */
164 * Local Variables:
165 * tab-width: 4
166 * c-indent-level: 4
167 * c-basic-offset: 4
168 * End: