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