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>
9 * Last Updated : $Date: 2004/03/28 00:28:58 $
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
)
33 if ((mailbox
= fopen(mbox_filename
, "r")) == NULL
) {
34 DM(pc
, DEBUG_ERROR
, "Error opening mailbox '%s': %s\n",
35 mbox_filename
, strerror(errno
));
42 /* count the messages in a mailbox */
43 static void countMessages(Pop3 pc
, const char *mbox_filename
)
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
);
57 while (fgets(buf
, BUF_SIZE
, F
)) {
59 /* a newline by itself terminates the header */
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
)
74 next_from_is_start_of_header
= 0;
75 if (is_header
&& !strncmp(buf
, STATUS_STR
, len_status
)
76 && strrchr(buf
, 'R')) {
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
;
88 /* check file status; hold on to file information used
89 to restore access time */
91 fileHasChanged(const char *mbox_filename
, time_t * atime
,
92 time_t * mtime
, off_t
* size
)
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
;
115 int mboxCheckHistory(Pop3 pc
)
117 char *mbox_filename
= backtickExpand(pc
, pc
->path
);
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
);
136 int mboxCreate(Pop3 pc
, const char *str
)
138 /* MBOX format: mbox:fullpathname */
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
);
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
);