xref: /haiku/src/servers/mail/main.cpp (revision f802f04acf5fc26d7812935def3c7f7448054dca)
1*f802f04aSAxel Dörfler /*
2*f802f04aSAxel Dörfler  * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3*f802f04aSAxel Dörfler  * Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
4*f802f04aSAxel Dörfler  *
5*f802f04aSAxel Dörfler  * Distributed under the terms of the MIT License.
6f7215ac8SNathan Whitehorn  */
7f7215ac8SNathan Whitehorn 
8f7215ac8SNathan Whitehorn 
9*f802f04aSAxel Dörfler //!	The daemon's inner workings
10*f802f04aSAxel Dörfler 
11*f802f04aSAxel Dörfler 
12f7215ac8SNathan Whitehorn #include <Application.h>
13f7215ac8SNathan Whitehorn #include <Message.h>
14f7215ac8SNathan Whitehorn #include <File.h>
15f7215ac8SNathan Whitehorn #include <MessageRunner.h>
16f7215ac8SNathan Whitehorn #include <Deskbar.h>
17f7215ac8SNathan Whitehorn #include <Roster.h>
18f7215ac8SNathan Whitehorn #include <Button.h>
19f7215ac8SNathan Whitehorn #include <StringView.h>
20f7215ac8SNathan Whitehorn #include <Mime.h>
21f7215ac8SNathan Whitehorn #include <Beep.h>
22f7215ac8SNathan Whitehorn #include <fs_index.h>
23f7215ac8SNathan Whitehorn #include <fs_info.h>
24f7215ac8SNathan Whitehorn #include <String.h>
25f7215ac8SNathan Whitehorn #include <VolumeRoster.h>
26f7215ac8SNathan Whitehorn #include <Query.h>
27f7215ac8SNathan Whitehorn #include <ChainRunner.h>
28f7215ac8SNathan Whitehorn #include <NodeMonitor.h>
29f7215ac8SNathan Whitehorn #include <Path.h>
30f7215ac8SNathan Whitehorn 
31f7215ac8SNathan Whitehorn #include <string.h>
32f7215ac8SNathan Whitehorn #include <stdio.h>
33f7215ac8SNathan Whitehorn #include <errno.h>
34c4a3b483SNathan Whitehorn #include <sys/socket.h>
35f7215ac8SNathan Whitehorn #include <map>
36f7215ac8SNathan Whitehorn 
37f7215ac8SNathan Whitehorn #include <E-mail.h>
38f7215ac8SNathan Whitehorn #include <MailSettings.h>
39f7215ac8SNathan Whitehorn #include <MailMessage.h>
40f7215ac8SNathan Whitehorn #include <status.h>
41f7215ac8SNathan Whitehorn #include <StringList.h>
42f7215ac8SNathan Whitehorn 
4384e0703cSAlexandre Deckner #include "DeskbarView.h"
44f7215ac8SNathan Whitehorn #include "LEDAnimation.h"
45f7215ac8SNathan Whitehorn 
46f7215ac8SNathan Whitehorn #include <MDRLanguage.h>
47f7215ac8SNathan Whitehorn 
489a8ef589SIngo Weinhold 
499a8ef589SIngo Weinhold using std::map;
50f7215ac8SNathan Whitehorn 
51f7215ac8SNathan Whitehorn typedef struct glorbal {
52f7215ac8SNathan Whitehorn 	size_t bytes;
53f7215ac8SNathan Whitehorn 	BStringList msgs;
54f7215ac8SNathan Whitehorn } snuzzwut;
55f7215ac8SNathan Whitehorn 
56*f802f04aSAxel Dörfler 
57*f802f04aSAxel Dörfler static BMailStatusWindow* sStatus;
58*f802f04aSAxel Dörfler 
59f7215ac8SNathan Whitehorn 
60f7215ac8SNathan Whitehorn class MailDaemonApp : public BApplication {
61f7215ac8SNathan Whitehorn public:
62*f802f04aSAxel Dörfler 								MailDaemonApp();
63f7215ac8SNathan Whitehorn 	virtual						~MailDaemonApp();
64f7215ac8SNathan Whitehorn 
65*f802f04aSAxel Dörfler 	virtual	void				MessageReceived(BMessage* message);
66*f802f04aSAxel Dörfler 	virtual	void				RefsReceived(BMessage* message);
67f7215ac8SNathan Whitehorn 
68f7215ac8SNathan Whitehorn 	virtual void				Pulse();
69f7215ac8SNathan Whitehorn 	virtual bool				QuitRequested();
70f7215ac8SNathan Whitehorn 	virtual void				ReadyToRun();
71f7215ac8SNathan Whitehorn 
72f7215ac8SNathan Whitehorn 			void				InstallDeskbarIcon();
73f7215ac8SNathan Whitehorn 			void				RemoveDeskbarIcon();
74f7215ac8SNathan Whitehorn 
75*f802f04aSAxel Dörfler 			void				RunChains(BList& list, BMessage* message);
76*f802f04aSAxel Dörfler 			void				SendPendingMessages(BMessage* message);
77*f802f04aSAxel Dörfler 			void				GetNewMessages(BMessage* message);
78f7215ac8SNathan Whitehorn 
79f7215ac8SNathan Whitehorn private:
80*f802f04aSAxel Dörfler 			void				_UpdateAutoCheck(bigtime_t interval);
81f7215ac8SNathan Whitehorn 
82*f802f04aSAxel Dörfler 			BMessageRunner*		fAutoCheckRunner;
83*f802f04aSAxel Dörfler 			BMailSettings		fSettingsFile;
84f7215ac8SNathan Whitehorn 
85*f802f04aSAxel Dörfler 			int32				fNewMessages;
86*f802f04aSAxel Dörfler 			bool				fCentralBeep;
87f7215ac8SNathan Whitehorn 				// TRUE to do a beep when the status window closes. This happens
88f7215ac8SNathan Whitehorn 				// when all mail has been received, so you get one beep for
89*f802f04aSAxel Dörfler 				// everything rather than individual beeps for each mail
90*f802f04aSAxel Dörfler 				// account.
91f7215ac8SNathan Whitehorn 				// Set to TRUE by the 'mcbp' message that the mail Notification
92f7215ac8SNathan Whitehorn 				// filter sends us, cleared when the beep is done.
93*f802f04aSAxel Dörfler 			BList				fFetchDoneRespondents;
94*f802f04aSAxel Dörfler 			BList				fQueries;
95f7215ac8SNathan Whitehorn 
96*f802f04aSAxel Dörfler 			LEDAnimation*		fLEDAnimation;
97f7215ac8SNathan Whitehorn 
98*f802f04aSAxel Dörfler 			BString				fAlertString;
99f7215ac8SNathan Whitehorn };
100f7215ac8SNathan Whitehorn 
101f7215ac8SNathan Whitehorn 
102*f802f04aSAxel Dörfler MailDaemonApp::MailDaemonApp()
103*f802f04aSAxel Dörfler 	:
104*f802f04aSAxel Dörfler 	BApplication("application/x-vnd.Be-POST")
105f7215ac8SNathan Whitehorn {
106*f802f04aSAxel Dörfler 	sStatus = new BMailStatusWindow(BRect(40, 400, 360, 400), "Mail Status",
107*f802f04aSAxel Dörfler 		fSettingsFile.ShowStatusWindow());
108*f802f04aSAxel Dörfler 	fAutoCheckRunner = NULL;
109f7215ac8SNathan Whitehorn }
110f7215ac8SNathan Whitehorn 
111f7215ac8SNathan Whitehorn 
112f7215ac8SNathan Whitehorn MailDaemonApp::~MailDaemonApp()
113f7215ac8SNathan Whitehorn {
114*f802f04aSAxel Dörfler 	delete fAutoCheckRunner;
115f7215ac8SNathan Whitehorn 
116*f802f04aSAxel Dörfler 	for (int32 i = 0; i < fQueries.CountItems(); i++)
117*f802f04aSAxel Dörfler 		delete (BQuery*)fQueries.ItemAt(i);
118f7215ac8SNathan Whitehorn 
119*f802f04aSAxel Dörfler 	delete fLEDAnimation;
120f7215ac8SNathan Whitehorn }
121f7215ac8SNathan Whitehorn 
122f7215ac8SNathan Whitehorn 
123f7215ac8SNathan Whitehorn void
124f7215ac8SNathan Whitehorn MailDaemonApp::ReadyToRun()
125f7215ac8SNathan Whitehorn {
126f7215ac8SNathan Whitehorn 	InstallDeskbarIcon();
127f7215ac8SNathan Whitehorn 
128*f802f04aSAxel Dörfler 	_UpdateAutoCheck(fSettingsFile.AutoCheckInterval());
129f7215ac8SNathan Whitehorn 
130f7215ac8SNathan Whitehorn 	BVolume volume;
131f7215ac8SNathan Whitehorn 	BVolumeRoster roster;
132f7215ac8SNathan Whitehorn 
133*f802f04aSAxel Dörfler 	fNewMessages = 0;
134f7215ac8SNathan Whitehorn 
135f7215ac8SNathan Whitehorn 	while (roster.GetNextVolume(&volume) == B_OK) {
136f7215ac8SNathan Whitehorn 		//{char name[255];volume.GetName(name);printf("Volume: %s\n",name);}
137f7215ac8SNathan Whitehorn 
138f7215ac8SNathan Whitehorn 		BQuery* query = new BQuery;
139f7215ac8SNathan Whitehorn 
140f7215ac8SNathan Whitehorn 		query->SetTarget(this);
141f7215ac8SNathan Whitehorn 		query->SetVolume(&volume);
142f7215ac8SNathan Whitehorn 		query->PushAttr(B_MAIL_ATTR_STATUS);
143f7215ac8SNathan Whitehorn 		query->PushString("New");
144f7215ac8SNathan Whitehorn 		query->PushOp(B_EQ);
145f7215ac8SNathan Whitehorn 		query->PushAttr("BEOS:TYPE");
146f7215ac8SNathan Whitehorn 		query->PushString("text/x-email");
147f7215ac8SNathan Whitehorn 		query->PushOp(B_EQ);
148f7215ac8SNathan Whitehorn 		query->PushAttr("BEOS:TYPE");
149f7215ac8SNathan Whitehorn 		query->PushString("text/x-partial-email");
150f7215ac8SNathan Whitehorn 		query->PushOp(B_EQ);
151f7215ac8SNathan Whitehorn 		query->PushOp(B_OR);
152f7215ac8SNathan Whitehorn 		query->PushOp(B_AND);
153f7215ac8SNathan Whitehorn 		query->Fetch();
154f7215ac8SNathan Whitehorn 
155f7215ac8SNathan Whitehorn 		BEntry entry;
156*f802f04aSAxel Dörfler 		while (query->GetNextEntry(&entry) == B_OK)
157*f802f04aSAxel Dörfler 			fNewMessages++;
158f7215ac8SNathan Whitehorn 
159*f802f04aSAxel Dörfler 		fQueries.AddItem(query);
160f7215ac8SNathan Whitehorn 	}
161f7215ac8SNathan Whitehorn 
162f7215ac8SNathan Whitehorn 	BString string;
163f7215ac8SNathan Whitehorn 	MDR_DIALECT_CHOICE(
164*f802f04aSAxel Dörfler 		if (fNewMessages > 0)
165*f802f04aSAxel Dörfler 			string << fNewMessages;
166f7215ac8SNathan Whitehorn 		else
167f7215ac8SNathan Whitehorn 			string << "No";
168*f802f04aSAxel Dörfler 		if (fNewMessages != 1)
169f7215ac8SNathan Whitehorn 			string << " new messages.";
170f7215ac8SNathan Whitehorn 		else
171f7215ac8SNathan Whitehorn 			string << " new message.";,
172*f802f04aSAxel Dörfler 		if (fNewMessages > 0)
173*f802f04aSAxel Dörfler 			string << fNewMessages << " 通の未読メッセージがあります ";
174f7215ac8SNathan Whitehorn 		else
175f7215ac8SNathan Whitehorn 			string << "未読メッセージはありません";
176f7215ac8SNathan Whitehorn 	);
177*f802f04aSAxel Dörfler 	fCentralBeep = false;
178*f802f04aSAxel Dörfler 	sStatus->SetDefaultMessage(string);
179f7215ac8SNathan Whitehorn 
180*f802f04aSAxel Dörfler 	fLEDAnimation = new LEDAnimation;
181f7215ac8SNathan Whitehorn 	SetPulseRate(1000000);
182f7215ac8SNathan Whitehorn }
183f7215ac8SNathan Whitehorn 
184f7215ac8SNathan Whitehorn 
185f7215ac8SNathan Whitehorn void
186f7215ac8SNathan Whitehorn MailDaemonApp::RefsReceived(BMessage* message)
187f7215ac8SNathan Whitehorn {
188*f802f04aSAxel Dörfler 	sStatus->Activate(true);
189f7215ac8SNathan Whitehorn 
190f7215ac8SNathan Whitehorn 	entry_ref ref;
191f7215ac8SNathan Whitehorn 	for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
192f7215ac8SNathan Whitehorn 		BNode node(&ref);
193f7215ac8SNathan Whitehorn 		if (node.InitCheck() < B_OK)
194f7215ac8SNathan Whitehorn 			continue;
195f7215ac8SNathan Whitehorn 
196f7215ac8SNathan Whitehorn 		BString uid;
197f7215ac8SNathan Whitehorn 		if (node.ReadAttrString("MAIL:unique_id", &uid) < 0)
198f7215ac8SNathan Whitehorn 			continue;
199f7215ac8SNathan Whitehorn 
200f7215ac8SNathan Whitehorn 		int32 id;
201f7215ac8SNathan Whitehorn 		if (node.ReadAttr("MAIL:chain", B_INT32_TYPE, 0, &id, sizeof(id)) < 0)
202f7215ac8SNathan Whitehorn 			continue;
203f7215ac8SNathan Whitehorn 
204f7215ac8SNathan Whitehorn 		int32 size;
205*f802f04aSAxel Dörfler 		if (node.ReadAttr("MAIL:fullsize", B_SIZE_T_TYPE, 0, &size,
206*f802f04aSAxel Dörfler 				sizeof(size)) < 0) {
207f7215ac8SNathan Whitehorn 			size = -1;
208*f802f04aSAxel Dörfler 		}
209f7215ac8SNathan Whitehorn 
210f7215ac8SNathan Whitehorn 		BPath path(&ref);
211*f802f04aSAxel Dörfler 		BMailChainRunner* runner = GetMailChainRunner(id, sStatus);
212*f802f04aSAxel Dörfler 		if (runner != NULL)
213f7215ac8SNathan Whitehorn 			runner->GetSingleMessage(uid.String(), size, &path);
214f7215ac8SNathan Whitehorn 	}
215f7215ac8SNathan Whitehorn }
216f7215ac8SNathan Whitehorn 
217f7215ac8SNathan Whitehorn 
218f7215ac8SNathan Whitehorn void
219*f802f04aSAxel Dörfler MailDaemonApp::_UpdateAutoCheck(bigtime_t interval)
220f7215ac8SNathan Whitehorn {
221f7215ac8SNathan Whitehorn 	if (interval > 0) {
222*f802f04aSAxel Dörfler 		if (fAutoCheckRunner != NULL) {
223*f802f04aSAxel Dörfler 			fAutoCheckRunner->SetInterval(interval);
224*f802f04aSAxel Dörfler 			fAutoCheckRunner->SetCount(-1);
225f7215ac8SNathan Whitehorn 		} else
226*f802f04aSAxel Dörfler 			fAutoCheckRunner = new BMessageRunner(be_app_messenger,
227*f802f04aSAxel Dörfler 				new BMessage('moto'), interval);
228f7215ac8SNathan Whitehorn 	} else {
229*f802f04aSAxel Dörfler 		delete fAutoCheckRunner;
230*f802f04aSAxel Dörfler 		fAutoCheckRunner = NULL;
231f7215ac8SNathan Whitehorn 	}
232f7215ac8SNathan Whitehorn }
233f7215ac8SNathan Whitehorn 
234f7215ac8SNathan Whitehorn 
235f7215ac8SNathan Whitehorn void
236f7215ac8SNathan Whitehorn MailDaemonApp::MessageReceived(BMessage* msg)
237f7215ac8SNathan Whitehorn {
238f7215ac8SNathan Whitehorn 	switch (msg->what) {
239f7215ac8SNathan Whitehorn 		case 'moto':
240*f802f04aSAxel Dörfler 			if (fSettingsFile.CheckOnlyIfPPPUp()) {
241*f802f04aSAxel Dörfler 				// TODO: check whether internet is up and running!
242f7215ac8SNathan Whitehorn 			}
243f7215ac8SNathan Whitehorn 			// supposed to fall through
244f7215ac8SNathan Whitehorn 		case 'mbth':	// check & send messages
245f7215ac8SNathan Whitehorn 			msg->what = 'msnd';
246*f802f04aSAxel Dörfler 			PostMessage(msg);
247f7215ac8SNathan Whitehorn 			// supposed to fall trough
248f7215ac8SNathan Whitehorn 		case 'mnow':	// check messages
249f7215ac8SNathan Whitehorn 			GetNewMessages(msg);
250f7215ac8SNathan Whitehorn 			break;
251*f802f04aSAxel Dörfler 
252f7215ac8SNathan Whitehorn 		case 'msnd':	// send messages
253f7215ac8SNathan Whitehorn 			SendPendingMessages(msg);
254f7215ac8SNathan Whitehorn 			break;
255f7215ac8SNathan Whitehorn 
256f7215ac8SNathan Whitehorn 		case 'mrrs':
257*f802f04aSAxel Dörfler 			fSettingsFile.Reload();
258*f802f04aSAxel Dörfler 			_UpdateAutoCheck(fSettingsFile.AutoCheckInterval());
259*f802f04aSAxel Dörfler 			sStatus->SetShowCriterion(fSettingsFile.ShowStatusWindow());
260f7215ac8SNathan Whitehorn 			break;
261f7215ac8SNathan Whitehorn 		case 'shst':	// when to show the status window
262f7215ac8SNathan Whitehorn 		{
263f7215ac8SNathan Whitehorn 			int32 mode;
264f7215ac8SNathan Whitehorn 			if (msg->FindInt32("ShowStatusWindow", &mode) == B_OK)
265*f802f04aSAxel Dörfler 				sStatus->SetShowCriterion(mode);
266f7215ac8SNathan Whitehorn 			break;
267f7215ac8SNathan Whitehorn 		}
268*f802f04aSAxel Dörfler 
269f7215ac8SNathan Whitehorn 		case 'lkch':	// status window look changed
270f7215ac8SNathan Whitehorn 		case 'wsch':	// workspace changed
271*f802f04aSAxel Dörfler 			sStatus->PostMessage(msg);
272f7215ac8SNathan Whitehorn 			break;
273f7215ac8SNathan Whitehorn 
274*f802f04aSAxel Dörfler 		case 'stwg':	// Status window gone
275*f802f04aSAxel Dörfler 		{
276*f802f04aSAxel Dörfler 			BMessage reply('mnuc');
277*f802f04aSAxel Dörfler 			reply.AddInt32("num_new_messages", fNewMessages);
278*f802f04aSAxel Dörfler 
279*f802f04aSAxel Dörfler 			while ((msg = (BMessage*)fFetchDoneRespondents.RemoveItem(0L))) {
280f7215ac8SNathan Whitehorn 				msg->SendReply(&reply);
281f7215ac8SNathan Whitehorn 				delete msg;
282f7215ac8SNathan Whitehorn 			}
283*f802f04aSAxel Dörfler 
284*f802f04aSAxel Dörfler 			if (fAlertString != B_EMPTY_STRING) {
285*f802f04aSAxel Dörfler 				fAlertString.Truncate(fAlertString.Length() - 1);
286*f802f04aSAxel Dörfler 				BAlert* alert = new BAlert(MDR_DIALECT_CHOICE("New Messages",
287*f802f04aSAxel Dörfler 					"新着メッセージ"), fAlertString.String(), "OK", NULL, NULL,
288*f802f04aSAxel Dörfler 					B_WIDTH_AS_USUAL);
289f7215ac8SNathan Whitehorn 				alert->SetFeel(B_NORMAL_WINDOW_FEEL);
290f7215ac8SNathan Whitehorn 				alert->Go(NULL);
291*f802f04aSAxel Dörfler 				fAlertString = B_EMPTY_STRING;
292f7215ac8SNathan Whitehorn 			}
293*f802f04aSAxel Dörfler 
294*f802f04aSAxel Dörfler 			if (fCentralBeep) {
295f7215ac8SNathan Whitehorn 				system_beep("New E-mail");
296*f802f04aSAxel Dörfler 				fCentralBeep = false;
297f7215ac8SNathan Whitehorn 			}
298f7215ac8SNathan Whitehorn 			break;
299f7215ac8SNathan Whitehorn 		}
300f7215ac8SNathan Whitehorn 
301*f802f04aSAxel Dörfler 		case 'mcbp':
302*f802f04aSAxel Dörfler 			if (fNewMessages > 0)
303*f802f04aSAxel Dörfler 				fCentralBeep = true;
304*f802f04aSAxel Dörfler 			break;
305*f802f04aSAxel Dörfler 
306*f802f04aSAxel Dörfler 		case 'mnum':	// Number of new messages
307*f802f04aSAxel Dörfler 		{
308*f802f04aSAxel Dörfler 			BMessage reply('mnuc');	// Mail New message Count
309*f802f04aSAxel Dörfler 			if (msg->FindBool("wait_for_fetch_done")) {
310*f802f04aSAxel Dörfler 				fFetchDoneRespondents.AddItem(DetachCurrentMessage());
311*f802f04aSAxel Dörfler 				break;
312f7215ac8SNathan Whitehorn 			}
313*f802f04aSAxel Dörfler 
314*f802f04aSAxel Dörfler 			reply.AddInt32("num_new_messages", fNewMessages);
315*f802f04aSAxel Dörfler 			msg->SendReply(&reply);
316f7215ac8SNathan Whitehorn 			break;
317*f802f04aSAxel Dörfler 		}
318*f802f04aSAxel Dörfler 
319*f802f04aSAxel Dörfler 		case 'mblk':	// Mail Blink
320*f802f04aSAxel Dörfler 			if (fNewMessages > 0)
321*f802f04aSAxel Dörfler 				fLEDAnimation->Start();
322f7215ac8SNathan Whitehorn 			break;
323*f802f04aSAxel Dörfler 
324*f802f04aSAxel Dörfler 		case 'enda':	// End Auto Check
325*f802f04aSAxel Dörfler 			delete fAutoCheckRunner;
326*f802f04aSAxel Dörfler 			fAutoCheckRunner = NULL;
327f7215ac8SNathan Whitehorn 			break;
328*f802f04aSAxel Dörfler 
329f7215ac8SNathan Whitehorn 		case 'numg':
330f7215ac8SNathan Whitehorn 		{
331*f802f04aSAxel Dörfler 			int32 numMessages = msg->FindInt32("num_messages");
332f7215ac8SNathan Whitehorn 			MDR_DIALECT_CHOICE(
333*f802f04aSAxel Dörfler 				fAlertString << numMessages << " new message";
334*f802f04aSAxel Dörfler 				if (numMessages > 1)
335*f802f04aSAxel Dörfler 					fAlertString << 's';
336f7215ac8SNathan Whitehorn 
337*f802f04aSAxel Dörfler 				fAlertString << " for " << msg->FindString("chain_name")
338*f802f04aSAxel Dörfler 					<< '\n';,
339f7215ac8SNathan Whitehorn 
340*f802f04aSAxel Dörfler 				fAlertString << msg->FindString("chain_name") << "より\n"
341*f802f04aSAxel Dörfler 					<< numMessages << " 通のメッセージが届きました  ";
342f7215ac8SNathan Whitehorn 			);
343f7215ac8SNathan Whitehorn 			break;
344*f802f04aSAxel Dörfler 		}
345*f802f04aSAxel Dörfler 
346f7215ac8SNathan Whitehorn 		case B_QUERY_UPDATE:
347f7215ac8SNathan Whitehorn 		{
348f7215ac8SNathan Whitehorn 			int32 what;
349f7215ac8SNathan Whitehorn 			msg->FindInt32("opcode", &what);
350f7215ac8SNathan Whitehorn 			switch (what) {
351f7215ac8SNathan Whitehorn 				case B_ENTRY_CREATED:
352*f802f04aSAxel Dörfler 					fNewMessages++;
353f7215ac8SNathan Whitehorn 					break;
354f7215ac8SNathan Whitehorn 				case B_ENTRY_REMOVED:
355*f802f04aSAxel Dörfler 					fNewMessages--;
356f7215ac8SNathan Whitehorn 					break;
357f7215ac8SNathan Whitehorn 			}
358f7215ac8SNathan Whitehorn 
359f7215ac8SNathan Whitehorn 			BString string;
360f7215ac8SNathan Whitehorn 
361f7215ac8SNathan Whitehorn 			MDR_DIALECT_CHOICE(
362*f802f04aSAxel Dörfler 				if (fNewMessages > 0)
363*f802f04aSAxel Dörfler 					string << fNewMessages;
364f7215ac8SNathan Whitehorn 				else
365f7215ac8SNathan Whitehorn 					string << "No";
366*f802f04aSAxel Dörfler 				if (fNewMessages != 1)
367f7215ac8SNathan Whitehorn 					string << " new messages.";
368f7215ac8SNathan Whitehorn 				else
369f7215ac8SNathan Whitehorn 					string << " new message.";,
370*f802f04aSAxel Dörfler 
371*f802f04aSAxel Dörfler 				if (fNewMessages > 0)
372*f802f04aSAxel Dörfler 					string << fNewMessages << " 通の未読メッセージがあります";
373f7215ac8SNathan Whitehorn 				else
374f7215ac8SNathan Whitehorn 					string << "未読メッセージはありません";
375f7215ac8SNathan Whitehorn 			);
376f7215ac8SNathan Whitehorn 
377*f802f04aSAxel Dörfler 			sStatus->SetDefaultMessage(string.String());
378f7215ac8SNathan Whitehorn 			break;
379f7215ac8SNathan Whitehorn 		}
380*f802f04aSAxel Dörfler 
381*f802f04aSAxel Dörfler 		default:
382f7215ac8SNathan Whitehorn 			BApplication::MessageReceived(msg);
383*f802f04aSAxel Dörfler 			break;
384*f802f04aSAxel Dörfler 	}
385f7215ac8SNathan Whitehorn }
386f7215ac8SNathan Whitehorn 
387f7215ac8SNathan Whitehorn 
388f7215ac8SNathan Whitehorn void
389f7215ac8SNathan Whitehorn MailDaemonApp::InstallDeskbarIcon()
390f7215ac8SNathan Whitehorn {
391f7215ac8SNathan Whitehorn 	BDeskbar deskbar;
392f7215ac8SNathan Whitehorn 
393f7215ac8SNathan Whitehorn 	if (!deskbar.HasItem("mail_daemon")) {
394f7215ac8SNathan Whitehorn 		BRoster roster;
395f7215ac8SNathan Whitehorn 		entry_ref ref;
396f7215ac8SNathan Whitehorn 
397f7215ac8SNathan Whitehorn 		status_t status = roster.FindApp("application/x-vnd.Be-POST", &ref);
398f7215ac8SNathan Whitehorn 		if (status < B_OK) {
399*f802f04aSAxel Dörfler 			fprintf(stderr, "Can't find application to tell deskbar: %s\n",
400*f802f04aSAxel Dörfler 				strerror(status));
401f7215ac8SNathan Whitehorn 			return;
402f7215ac8SNathan Whitehorn 		}
403f7215ac8SNathan Whitehorn 
404f7215ac8SNathan Whitehorn 		status = deskbar.AddItem(&ref);
405f7215ac8SNathan Whitehorn 		if (status < B_OK) {
406f7215ac8SNathan Whitehorn 			fprintf(stderr, "Can't add deskbar replicant: %s\n", strerror(status));
407f7215ac8SNathan Whitehorn 			return;
408f7215ac8SNathan Whitehorn 		}
409f7215ac8SNathan Whitehorn 	}
410f7215ac8SNathan Whitehorn }
411f7215ac8SNathan Whitehorn 
412f7215ac8SNathan Whitehorn 
413f7215ac8SNathan Whitehorn void
414f7215ac8SNathan Whitehorn MailDaemonApp::RemoveDeskbarIcon()
415f7215ac8SNathan Whitehorn {
416f7215ac8SNathan Whitehorn 	BDeskbar deskbar;
417f7215ac8SNathan Whitehorn 	if (deskbar.HasItem("mail_daemon"))
418f7215ac8SNathan Whitehorn 		deskbar.RemoveItem("mail_daemon");
419f7215ac8SNathan Whitehorn }
420f7215ac8SNathan Whitehorn 
421f7215ac8SNathan Whitehorn 
422f7215ac8SNathan Whitehorn bool
423f7215ac8SNathan Whitehorn MailDaemonApp::QuitRequested()
424f7215ac8SNathan Whitehorn {
425f7215ac8SNathan Whitehorn 	RemoveDeskbarIcon();
426f7215ac8SNathan Whitehorn 
427f7215ac8SNathan Whitehorn 	return true;
428f7215ac8SNathan Whitehorn }
429f7215ac8SNathan Whitehorn 
430f7215ac8SNathan Whitehorn 
431f7215ac8SNathan Whitehorn void
432f7215ac8SNathan Whitehorn MailDaemonApp::RunChains(BList& list, BMessage* msg)
433f7215ac8SNathan Whitehorn {
434f7215ac8SNathan Whitehorn 	BMailChain* chain;
435f7215ac8SNathan Whitehorn 
436f7215ac8SNathan Whitehorn 	int32 index = 0, id;
437f7215ac8SNathan Whitehorn 	for (; msg->FindInt32("chain", index, &id) == B_OK; index++) {
438f7215ac8SNathan Whitehorn 		for (int32 i = 0; i < list.CountItems(); i++) {
439f7215ac8SNathan Whitehorn 			chain = (BMailChain*)list.ItemAt(i);
440f7215ac8SNathan Whitehorn 
441cfbb3703Sshatty 			if (chain->ID() == (unsigned)id) {
442*f802f04aSAxel Dörfler 				chain->RunChain(sStatus, true, false, true);
443f7215ac8SNathan Whitehorn 				list.RemoveItem(i);	// the chain runner deletes the chain
444f7215ac8SNathan Whitehorn 				break;
445f7215ac8SNathan Whitehorn 			}
446f7215ac8SNathan Whitehorn 		}
447f7215ac8SNathan Whitehorn 	}
448f7215ac8SNathan Whitehorn 
449f7215ac8SNathan Whitehorn 	if (index == 0) {
450f7215ac8SNathan Whitehorn 		// invoke all chains
451f7215ac8SNathan Whitehorn 		for (int32 i = 0; i < list.CountItems(); i++) {
452f7215ac8SNathan Whitehorn 			chain = (BMailChain*)list.ItemAt(i);
453f7215ac8SNathan Whitehorn 
454*f802f04aSAxel Dörfler 			chain->RunChain(sStatus, true, false, true);
455f7215ac8SNathan Whitehorn 		}
456f7215ac8SNathan Whitehorn 	} else {
457f7215ac8SNathan Whitehorn 		// delete unused chains
458f7215ac8SNathan Whitehorn 		for (int32 i = list.CountItems(); i-- > 0;)
459f7215ac8SNathan Whitehorn 			delete (BMailChain*)list.RemoveItem(i);
460f7215ac8SNathan Whitehorn 	}
461f7215ac8SNathan Whitehorn }
462f7215ac8SNathan Whitehorn 
463f7215ac8SNathan Whitehorn 
464f7215ac8SNathan Whitehorn void
465f7215ac8SNathan Whitehorn MailDaemonApp::GetNewMessages(BMessage* msg)
466f7215ac8SNathan Whitehorn {
467f7215ac8SNathan Whitehorn 	BList list;
468f7215ac8SNathan Whitehorn 	GetInboundMailChains(&list);
469f7215ac8SNathan Whitehorn 
470f7215ac8SNathan Whitehorn 	RunChains(list,msg);
471f7215ac8SNathan Whitehorn }
472f7215ac8SNathan Whitehorn 
473f7215ac8SNathan Whitehorn 
474f7215ac8SNathan Whitehorn void
475f7215ac8SNathan Whitehorn MailDaemonApp::SendPendingMessages(BMessage* msg)
476f7215ac8SNathan Whitehorn {
477f7215ac8SNathan Whitehorn 	BVolumeRoster roster;
478f7215ac8SNathan Whitehorn 	BVolume volume;
479f7215ac8SNathan Whitehorn 
480f7215ac8SNathan Whitehorn 	while (roster.GetNextVolume(&volume) == B_OK) {
481f7215ac8SNathan Whitehorn 		BQuery query;
482f7215ac8SNathan Whitehorn 		query.SetVolume(&volume);
483f7215ac8SNathan Whitehorn 		query.PushAttr(B_MAIL_ATTR_FLAGS);
484f7215ac8SNathan Whitehorn 		query.PushInt32(B_MAIL_PENDING);
485f7215ac8SNathan Whitehorn 		query.PushOp(B_EQ);
486f7215ac8SNathan Whitehorn 
487f7215ac8SNathan Whitehorn 		query.PushAttr(B_MAIL_ATTR_FLAGS);
488f7215ac8SNathan Whitehorn 		query.PushInt32(B_MAIL_PENDING | B_MAIL_SAVE);
489f7215ac8SNathan Whitehorn 		query.PushOp(B_EQ);
490f7215ac8SNathan Whitehorn 
491f7215ac8SNathan Whitehorn 		query.PushOp(B_OR);
492f7215ac8SNathan Whitehorn 
493*f802f04aSAxel Dörfler 		int32 chainID = -1;
494f7215ac8SNathan Whitehorn 
495*f802f04aSAxel Dörfler 		if (msg->FindInt32("chain", &chainID) == B_OK) {
496f7215ac8SNathan Whitehorn 			query.PushAttr("MAIL:chain");
497*f802f04aSAxel Dörfler 			query.PushInt32(chainID);
498f7215ac8SNathan Whitehorn 			query.PushOp(B_EQ);
499f7215ac8SNathan Whitehorn 			query.PushOp(B_AND);
500*f802f04aSAxel Dörfler 		} else
501*f802f04aSAxel Dörfler 			chainID = -1;
502f7215ac8SNathan Whitehorn 
503f7215ac8SNathan Whitehorn 		if (!msg->HasString("message_path")) {
504*f802f04aSAxel Dörfler 			if (chainID == -1) {
505f7215ac8SNathan Whitehorn 				map<int32, snuzzwut*> messages;
506f7215ac8SNathan Whitehorn 
507f7215ac8SNathan Whitehorn 				query.Fetch();
508f7215ac8SNathan Whitehorn 				BEntry entry;
509f7215ac8SNathan Whitehorn 				BPath path;
510f7215ac8SNathan Whitehorn 				BNode node;
511*f802f04aSAxel Dörfler 				int32 chain;
512*f802f04aSAxel Dörfler 				int32 defaultChain(BMailSettings().DefaultOutboundChainID());
513f7215ac8SNathan Whitehorn 				off_t size;
514f7215ac8SNathan Whitehorn 
515f7215ac8SNathan Whitehorn 				while (query.GetNextEntry(&entry) == B_OK) {
516f7215ac8SNathan Whitehorn 					while (node.SetTo(&entry) == B_BUSY) snooze(100);
517f7215ac8SNathan Whitehorn 					if (node.ReadAttr("MAIL:chain",B_INT32_TYPE,0,&chain,4) < B_OK)
518*f802f04aSAxel Dörfler 						chain = defaultChain;
519f7215ac8SNathan Whitehorn 					entry.GetPath(&path);
520f7215ac8SNathan Whitehorn 					node.GetSize(&size);
521f7215ac8SNathan Whitehorn 					if (messages[chain] == NULL) {
522f7215ac8SNathan Whitehorn 						messages[chain] = new snuzzwut;
523f7215ac8SNathan Whitehorn 						messages[chain]->bytes = 0;
524f7215ac8SNathan Whitehorn 					}
525f7215ac8SNathan Whitehorn 
526f7215ac8SNathan Whitehorn 					messages[chain]->msgs += path.Path();
527f7215ac8SNathan Whitehorn 					messages[chain]->bytes += size;
528f7215ac8SNathan Whitehorn 				}
529f7215ac8SNathan Whitehorn 
530f7215ac8SNathan Whitehorn 				map<int32, snuzzwut*>::iterator iter = messages.begin();
531f7215ac8SNathan Whitehorn 				map<int32, snuzzwut*>::iterator end = messages.end();
532f7215ac8SNathan Whitehorn 				while (iter != end) {
533*f802f04aSAxel Dörfler 					if (iter->first > 0 && BMailChain(iter->first)
534*f802f04aSAxel Dörfler 							.ChainDirection() == outbound) {
535*f802f04aSAxel Dörfler 						BMailChainRunner* runner
536*f802f04aSAxel Dörfler 							= GetMailChainRunner(iter->first, sStatus);
537*f802f04aSAxel Dörfler 						runner->GetMessages(&messages[iter->first]->msgs,
538*f802f04aSAxel Dörfler 							messages[iter->first]->bytes);
539f7215ac8SNathan Whitehorn 						delete messages[iter->first];
540f7215ac8SNathan Whitehorn 						runner->Stop();
541f7215ac8SNathan Whitehorn 					}
542f7215ac8SNathan Whitehorn 
543f7215ac8SNathan Whitehorn 					iter++;
544f7215ac8SNathan Whitehorn 				}
545f7215ac8SNathan Whitehorn 			} else {
546f7215ac8SNathan Whitehorn 				BStringList ids;
547f7215ac8SNathan Whitehorn 				size_t bytes = 0;
548f7215ac8SNathan Whitehorn 
549f7215ac8SNathan Whitehorn 				query.Fetch();
550f7215ac8SNathan Whitehorn 				BEntry entry;
551f7215ac8SNathan Whitehorn 				BPath path;
552f7215ac8SNathan Whitehorn 				BNode node;
553f7215ac8SNathan Whitehorn 				off_t size;
554f7215ac8SNathan Whitehorn 
555f7215ac8SNathan Whitehorn 				while (query.GetNextEntry(&entry) == B_OK) {
556f7215ac8SNathan Whitehorn 					node.SetTo(&entry);
557f7215ac8SNathan Whitehorn 					entry.GetPath(&path);
558f7215ac8SNathan Whitehorn 					node.GetSize(&size);
559f7215ac8SNathan Whitehorn 					ids += path.Path();
560f7215ac8SNathan Whitehorn 					bytes += size;
561f7215ac8SNathan Whitehorn 				}
562f7215ac8SNathan Whitehorn 
563*f802f04aSAxel Dörfler 				BMailChainRunner* runner
564*f802f04aSAxel Dörfler 					= GetMailChainRunner(chainID, sStatus);
565f7215ac8SNathan Whitehorn 				runner->GetMessages(&ids, bytes);
566f7215ac8SNathan Whitehorn 				runner->Stop();
567f7215ac8SNathan Whitehorn 			}
568f7215ac8SNathan Whitehorn 		} else {
569f7215ac8SNathan Whitehorn 			const char* path;
570*f802f04aSAxel Dörfler 			if (msg->FindString("message_path", &path) != B_OK)
571*f802f04aSAxel Dörfler 				return;
572*f802f04aSAxel Dörfler 
573*f802f04aSAxel Dörfler 			off_t size;
574*f802f04aSAxel Dörfler 			if (BNode(path).GetSize(&size) != B_OK)
575*f802f04aSAxel Dörfler 				return;
576*f802f04aSAxel Dörfler 
577f7215ac8SNathan Whitehorn 			BStringList ids;
578f7215ac8SNathan Whitehorn 			ids += path;
579*f802f04aSAxel Dörfler 
580*f802f04aSAxel Dörfler 			BMailChainRunner* runner = GetMailChainRunner(chainID, sStatus);
581f7215ac8SNathan Whitehorn 			runner->GetMessages(&ids, size);
582f7215ac8SNathan Whitehorn 			runner->Stop();
583f7215ac8SNathan Whitehorn 		}
584f7215ac8SNathan Whitehorn 	}
585f7215ac8SNathan Whitehorn }
586f7215ac8SNathan Whitehorn 
587f7215ac8SNathan Whitehorn 
588f7215ac8SNathan Whitehorn void
589f7215ac8SNathan Whitehorn MailDaemonApp::Pulse()
590f7215ac8SNathan Whitehorn {
591f7215ac8SNathan Whitehorn 	bigtime_t idle = idle_time();
592*f802f04aSAxel Dörfler 	if (fLEDAnimation->IsRunning() && idle < 100000)
593*f802f04aSAxel Dörfler 		fLEDAnimation->Stop();
594f7215ac8SNathan Whitehorn }
595f7215ac8SNathan Whitehorn 
596*f802f04aSAxel Dörfler 
597f7215ac8SNathan Whitehorn //	#pragma mark -
598f7215ac8SNathan Whitehorn 
599f7215ac8SNathan Whitehorn 
600f7215ac8SNathan Whitehorn void
601f7215ac8SNathan Whitehorn makeIndices()
602f7215ac8SNathan Whitehorn {
603*f802f04aSAxel Dörfler 	const char* stringIndices[] = {
604*f802f04aSAxel Dörfler 		B_MAIL_ATTR_ACCOUNT, B_MAIL_ATTR_CC, B_MAIL_ATTR_FROM, B_MAIL_ATTR_NAME,
605*f802f04aSAxel Dörfler 		B_MAIL_ATTR_PRIORITY, B_MAIL_ATTR_REPLY, B_MAIL_ATTR_STATUS,
606*f802f04aSAxel Dörfler 		B_MAIL_ATTR_SUBJECT, B_MAIL_ATTR_TO, B_MAIL_ATTR_THREAD,
607*f802f04aSAxel Dörfler 		NULL
608*f802f04aSAxel Dörfler 	};
609f7215ac8SNathan Whitehorn 
610f7215ac8SNathan Whitehorn 	// add mail indices for all devices capable of querying
611f7215ac8SNathan Whitehorn 
612f7215ac8SNathan Whitehorn 	int32 cookie = 0;
613f7215ac8SNathan Whitehorn 	dev_t device;
614f7215ac8SNathan Whitehorn 	while ((device = next_dev(&cookie)) >= B_OK) {
615f7215ac8SNathan Whitehorn 		fs_info info;
616*f802f04aSAxel Dörfler 		if (fs_stat_dev(device, &info) < 0
617*f802f04aSAxel Dörfler 			|| (info.flags & B_FS_HAS_QUERY) == 0)
618f7215ac8SNathan Whitehorn 			continue;
619f7215ac8SNathan Whitehorn 
620f7215ac8SNathan Whitehorn 		// Work-around for misbehaviour of earlier versions - should be
621f7215ac8SNathan Whitehorn 		// kept in for some time.
622f7215ac8SNathan Whitehorn 		// It removes the B_MAIL_ATTR_FLAGS if it is of B_STRING_TYPE,
623f7215ac8SNathan Whitehorn 		// because that's what the MDR created before...
624f7215ac8SNathan Whitehorn 		index_info indexInfo;
625f7215ac8SNathan Whitehorn 		if (fs_stat_index(device, B_MAIL_ATTR_FLAGS, &indexInfo) == 0
626f7215ac8SNathan Whitehorn 			&& indexInfo.type == B_STRING_TYPE)
627f7215ac8SNathan Whitehorn 			fs_remove_index(device, B_MAIL_ATTR_FLAGS);
628f7215ac8SNathan Whitehorn 
629f7215ac8SNathan Whitehorn 		for (int32 i = 0; stringIndices[i]; i++)
630f7215ac8SNathan Whitehorn 			fs_create_index(device, stringIndices[i], B_STRING_TYPE, 0);
631f7215ac8SNathan Whitehorn 
632f7215ac8SNathan Whitehorn 		fs_create_index(device, "MAIL:draft", B_INT32_TYPE, 0);
633f7215ac8SNathan Whitehorn 		fs_create_index(device, B_MAIL_ATTR_WHEN, B_INT32_TYPE, 0);
634f7215ac8SNathan Whitehorn 		fs_create_index(device, B_MAIL_ATTR_FLAGS, B_INT32_TYPE, 0);
635f7215ac8SNathan Whitehorn 		fs_create_index(device, "MAIL:chain", B_INT32_TYPE, 0);
636c3a2f393SNathan Whitehorn 		fs_create_index(device, "MAIL:pending_chain", B_INT32_TYPE, 0);
637f7215ac8SNathan Whitehorn 	}
638f7215ac8SNathan Whitehorn }
639f7215ac8SNathan Whitehorn 
640f7215ac8SNathan Whitehorn 
641f7215ac8SNathan Whitehorn void
642*f802f04aSAxel Dörfler addAttribute(BMessage& msg, const char* name, const char* publicName,
643*f802f04aSAxel Dörfler 	int32 type = B_STRING_TYPE, bool viewable = true, bool editable = false,
644*f802f04aSAxel Dörfler 	int32 width = 200)
645f7215ac8SNathan Whitehorn {
646f7215ac8SNathan Whitehorn 	msg.AddString("attr:name", name);
647f7215ac8SNathan Whitehorn 	msg.AddString("attr:public_name", publicName);
648f7215ac8SNathan Whitehorn 	msg.AddInt32("attr:type", type);
649f7215ac8SNathan Whitehorn 	msg.AddBool("attr:viewable", viewable);
650f7215ac8SNathan Whitehorn 	msg.AddBool("attr:editable", editable);
651f7215ac8SNathan Whitehorn 	msg.AddInt32("attr:width", width);
652f7215ac8SNathan Whitehorn 	msg.AddInt32("attr:alignment", B_ALIGN_LEFT);
653f7215ac8SNathan Whitehorn }
654f7215ac8SNathan Whitehorn 
655f7215ac8SNathan Whitehorn 
656f7215ac8SNathan Whitehorn void
657f7215ac8SNathan Whitehorn makeMimeType(bool remakeMIMETypes)
658f7215ac8SNathan Whitehorn {
659f7215ac8SNathan Whitehorn 	// Add MIME database entries for the e-mail file types we handle.  Either
660f7215ac8SNathan Whitehorn 	// do a full rebuild from nothing, or just add on the new attributes that
661f7215ac8SNathan Whitehorn 	// we support which the regular BeOS mail daemon didn't have.
662f7215ac8SNathan Whitehorn 
663f7215ac8SNathan Whitehorn 	const char* types[2] = {"text/x-email", "text/x-partial-email"};
664f7215ac8SNathan Whitehorn 	BMimeType mime;
665f7215ac8SNathan Whitehorn 	BMessage info;
666f7215ac8SNathan Whitehorn 
667*f802f04aSAxel Dörfler 	for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); i++) {
668f7215ac8SNathan Whitehorn 		info.MakeEmpty();
669f7215ac8SNathan Whitehorn 		mime.SetTo(types[i]);
670f7215ac8SNathan Whitehorn 		if (mime.InitCheck() != B_OK) {
671f7215ac8SNathan Whitehorn 			fputs("could not init mime type.\n", stderr);
672f7215ac8SNathan Whitehorn 			return;
673f7215ac8SNathan Whitehorn 		}
674f7215ac8SNathan Whitehorn 
675f7215ac8SNathan Whitehorn 		if (!mime.IsInstalled() || remakeMIMETypes) {
676f7215ac8SNathan Whitehorn 			// install the full mime type
677f7215ac8SNathan Whitehorn 			mime.Delete ();
678f7215ac8SNathan Whitehorn 			mime.Install();
679f7215ac8SNathan Whitehorn 
680f7215ac8SNathan Whitehorn 			// Set up the list of e-mail related attributes that Tracker will
681f7215ac8SNathan Whitehorn 			// let you display in columns for e-mail messages.
682f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_NAME, "Name");
683f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_SUBJECT, "Subject");
684f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_TO, "To");
685f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_CC, "Cc");
686f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_FROM, "From");
687f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_REPLY, "Reply To");
688f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_STATUS, "Status");
689*f802f04aSAxel Dörfler 			addAttribute(info, B_MAIL_ATTR_PRIORITY, "Priority", B_STRING_TYPE,
690*f802f04aSAxel Dörfler 				true, true, 40);
691*f802f04aSAxel Dörfler 			addAttribute(info, B_MAIL_ATTR_WHEN, "When", B_TIME_TYPE, true,
692*f802f04aSAxel Dörfler 				false, 150);
693f7215ac8SNathan Whitehorn 			addAttribute(info, B_MAIL_ATTR_THREAD, "Thread");
694*f802f04aSAxel Dörfler 			addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account", B_STRING_TYPE,
695*f802f04aSAxel Dörfler 				true, false, 100);
696f7215ac8SNathan Whitehorn 			mime.SetAttrInfo(&info);
697f7215ac8SNathan Whitehorn 
698f7215ac8SNathan Whitehorn 			if (i == 0) {
699f7215ac8SNathan Whitehorn 				mime.SetShortDescription("E-mail");
700f7215ac8SNathan Whitehorn 				mime.SetLongDescription("Electronic Mail Message");
701f7215ac8SNathan Whitehorn 				mime.SetPreferredApp("application/x-vnd.Be-MAIL");
702f7215ac8SNathan Whitehorn 			} else {
703f7215ac8SNathan Whitehorn 				mime.SetShortDescription("Partial E-mail");
704f7215ac8SNathan Whitehorn 				mime.SetLongDescription("A Partially Downloaded E-mail");
705f7215ac8SNathan Whitehorn 				mime.SetPreferredApp("application/x-vnd.Be-POST");
706f7215ac8SNathan Whitehorn 			}
707f7215ac8SNathan Whitehorn 		} else {
708*f802f04aSAxel Dörfler 			// Just add the e-mail related attribute types we use to the MIME
709*f802f04aSAxel Dörfler 			// system.
710f7215ac8SNathan Whitehorn 			mime.GetAttrInfo(&info);
711*f802f04aSAxel Dörfler 			bool hasAccount = false;
712*f802f04aSAxel Dörfler 			bool hasThread = false;
713*f802f04aSAxel Dörfler 			bool hasSize = false;
714f7215ac8SNathan Whitehorn 			const char* result;
715*f802f04aSAxel Dörfler 			for (int32 index = 0; info.FindString("attr:name", index, &result)
716*f802f04aSAxel Dörfler 					== B_OK; index++) {
717f7215ac8SNathan Whitehorn 				if (!strcmp(result, B_MAIL_ATTR_ACCOUNT))
718f7215ac8SNathan Whitehorn 					hasAccount = true;
719f7215ac8SNathan Whitehorn 				if (!strcmp(result, B_MAIL_ATTR_THREAD))
720f7215ac8SNathan Whitehorn 					hasThread = true;
721f7215ac8SNathan Whitehorn 				if (!strcmp(result, "MAIL:fullsize"))
722f7215ac8SNathan Whitehorn 					hasSize = true;
723f7215ac8SNathan Whitehorn 			}
724f7215ac8SNathan Whitehorn 
725*f802f04aSAxel Dörfler 			if (!hasAccount) {
726*f802f04aSAxel Dörfler 				addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account",
727*f802f04aSAxel Dörfler 					B_STRING_TYPE, true, false, 100);
728*f802f04aSAxel Dörfler 			}
729f7215ac8SNathan Whitehorn 			if (!hasThread)
730f7215ac8SNathan Whitehorn 				addAttribute(info, B_MAIL_ATTR_THREAD, "Thread");
731f7215ac8SNathan Whitehorn 			/*if (!hasSize)
732f7215ac8SNathan Whitehorn 				addAttribute(info,"MAIL:fullsize","Message Size",B_SIZE_T_TYPE,true,false,100);*/
733*f802f04aSAxel Dörfler 			// TODO: Tracker can't display SIZT attributes. What a pain.
734f7215ac8SNathan Whitehorn 			if (!hasAccount || !hasThread/* || !hasSize*/)
735f7215ac8SNathan Whitehorn 				mime.SetAttrInfo(&info);
736f7215ac8SNathan Whitehorn 		}
737f7215ac8SNathan Whitehorn 		mime.Unset();
738f7215ac8SNathan Whitehorn 	}
739f7215ac8SNathan Whitehorn }
740f7215ac8SNathan Whitehorn 
741f7215ac8SNathan Whitehorn 
742f7215ac8SNathan Whitehorn int
743f7215ac8SNathan Whitehorn main(int argc, const char** argv)
744f7215ac8SNathan Whitehorn {
745f7215ac8SNathan Whitehorn 	bool remakeMIMETypes = false;
746f7215ac8SNathan Whitehorn 
747f7215ac8SNathan Whitehorn 	for (int i = 1; i < argc; i++) {
748f7215ac8SNathan Whitehorn 		if (strcmp(argv[i], "-E") == 0) {
749f7215ac8SNathan Whitehorn 			if (!BMailSettings().DaemonAutoStarts())
750f7215ac8SNathan Whitehorn 				return 0;
751f7215ac8SNathan Whitehorn 		}
752f7215ac8SNathan Whitehorn 		if (strcmp(argv[i], "-M") == 0) {
753f7215ac8SNathan Whitehorn 			remakeMIMETypes = true;
754f7215ac8SNathan Whitehorn 		}
755f7215ac8SNathan Whitehorn 	}
756f7215ac8SNathan Whitehorn 
757f7215ac8SNathan Whitehorn 	MailDaemonApp app;
758f7215ac8SNathan Whitehorn 
759f7215ac8SNathan Whitehorn 	// install MimeTypes, attributes, indices, and the
760f7215ac8SNathan Whitehorn 	// system beep add startup
761f7215ac8SNathan Whitehorn 
762f7215ac8SNathan Whitehorn 	makeMimeType(remakeMIMETypes);
763f7215ac8SNathan Whitehorn 	makeIndices();
764f7215ac8SNathan Whitehorn 	add_system_beep_event("New E-mail");
765f7215ac8SNathan Whitehorn 
766f7215ac8SNathan Whitehorn 	be_app->Run();
767f7215ac8SNathan Whitehorn 	return 0;
768f7215ac8SNathan Whitehorn }
769f7215ac8SNathan Whitehorn 
770