1 /*
2 ** Copyright 2002, Double Precision Inc.
3 **
4 ** See COPYING for distribution information.
5 */
6 #include "libmail_config.h"
7 #include "mboxread.H"
8 #include "mboxmagictag.H"
9 #include "file.H"
10
11 #include <ctype.h>
12 #include <errno.h>
13
14 using namespace std;
15
GenericReadTask(mail::mbox & mboxAccount,mail::callback::message & callbackArg,string uidArg,size_t messageNumberArg,bool peekArg,mail::readMode readTypeArg)16 mail::mbox::GenericReadTask::GenericReadTask(mail::mbox &mboxAccount,
17 mail::callback::message
18 &callbackArg,
19 string uidArg,
20 size_t messageNumberArg,
21 bool peekArg,
22 mail::readMode
23 readTypeArg)
24 : LockTask(mboxAccount, callbackArg),
25 callback(callbackArg),
26 uid(uidArg),
27 messageNumber(messageNumberArg),
28 peek(peekArg),
29 readType(readTypeArg)
30 {
31 }
32
~GenericReadTask()33 mail::mbox::GenericReadTask::~GenericReadTask()
34 {
35 }
36
locked(mail::file & file)37 bool mail::mbox::GenericReadTask::locked(mail::file &file)
38 {
39 if (!mboxAccount.verifyUid(uid, messageNumber, callback))
40 {
41 done();
42 return true;
43 }
44
45 mail::ptr<mail::mbox> me= &mboxAccount;
46
47 off_t p=mboxAccount.folderMessageIndex[mboxAccount.uidmap.find(uid)->second]
48 .startingPos;
49
50 if (fseek(file, p, SEEK_SET) < 0)
51 {
52 fail(strerror(errno));
53 return true;
54 }
55
56 bool firstLine=true;
57 bool inHeaders=true;
58
59 string header="";
60
61 while (!feof(file) && !me.isDestroyed())
62 {
63 string line=file.getline();
64
65 if (line.size() == 0 && feof(file))
66 break;
67
68 if (strncmp(line.c_str(), "From ", 5) == 0)
69 {
70 if (firstLine)
71 continue;
72
73 break;
74 }
75
76 if (firstLine)
77 {
78 firstLine=false;
79
80 if (mail::mboxMagicTag(line,
81 mboxAccount.keywordHashtable)
82 .good())
83 continue; // Ignore the magic tag line
84 }
85
86 if (inHeaders)
87 {
88 if (line.size() == 0)
89 inHeaders=false;
90
91 if (readType == mail::readHeadersFolded)
92 {
93 const char *p=line.c_str();
94
95 if (line.size() > 0 &&
96 unicode_isspace((unsigned char)*p))
97 {
98 while (unicode_isspace((unsigned char)*p))
99 p++;
100
101 header += " ";
102 header += p;
103 continue;
104 }
105
106 if (header.size() > 0)
107 {
108 header += "\n";
109 callback.messageTextCallback(messageNumber,
110 header);
111 }
112 header=line;
113 continue;
114 }
115
116 line += "\n";
117 callback.messageTextCallback(messageNumber, line);
118 continue;
119 }
120
121 if (readType != mail::readBoth &&
122 readType != mail::readContents)
123 {
124 header="";
125 break;
126 }
127
128 line += "\n";
129
130 const char *p=line.c_str();
131
132 if (*p == '>')
133 {
134 while (*p == '>')
135 p++;
136
137 if (strncmp(p, "From ", 5) == 0)
138 line=line.substr(1);
139 // Dequote a >From_ line.
140 }
141
142 callback.messageTextCallback(messageNumber, line);
143 }
144
145 if (header.size() > 0) // Only headers, something got left over.
146 {
147 header += "\n";
148 callback.messageTextCallback(messageNumber, header);
149 }
150
151 if (!me.isDestroyed() && !peek &&
152 mboxAccount.index[messageNumber].unread)
153 {
154 mboxAccount.index[messageNumber].unread=false;
155 mboxAccount.folderDirty=true;
156 if (mboxAccount.currentFolderCallback)
157 mboxAccount.currentFolderCallback
158 ->messageChanged(messageNumber);
159 }
160
161
162 callback.success("Folder locked.");
163 done();
164 return true;
165 }
166